Gilles Peskine | 6c723a2 | 2020-04-17 16:57:52 +0200 | [diff] [blame] | 1 | |
| 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" |
| 3 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| 4 | |
| 5 | <html xmlns="http://www.w3.org/1999/xhtml"> |
| 6 | <head> |
| 7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| 8 | <title>Functionality overview — PSA Crypto API 1.0.0 documentation</title> |
| 9 | <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" /> |
| 10 | <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> |
| 11 | <script type="text/javascript"> |
| 12 | var DOCUMENTATION_OPTIONS = { |
| 13 | URL_ROOT: '../', |
| 14 | VERSION: '1.0.0', |
| 15 | COLLAPSE_INDEX: false, |
| 16 | FILE_SUFFIX: '.html', |
| 17 | HAS_SOURCE: true, |
| 18 | SOURCELINK_SUFFIX: '.txt' |
| 19 | }; |
| 20 | </script> |
| 21 | <script type="text/javascript" src="../_static/jquery.js"></script> |
| 22 | <script type="text/javascript" src="../_static/underscore.js"></script> |
| 23 | <script type="text/javascript" src="../_static/doctools.js"></script> |
| 24 | <link rel="index" title="Index" href="../genindex.html" /> |
| 25 | <link rel="search" title="Search" href="../search.html" /> |
| 26 | <link rel="next" title="Sample architectures" href="sample-arch.html" /> |
| 27 | <link rel="prev" title="Design goals" href="goals.html" /> |
| 28 | |
| 29 | <link rel="stylesheet" href="../_static/custom.css" type="text/css" /> |
| 30 | |
| 31 | <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" /> |
| 32 | |
| 33 | </head> |
| 34 | <body> |
| 35 | |
| 36 | |
| 37 | <div class="document"> |
| 38 | <div class="documentwrapper"> |
| 39 | <div class="bodywrapper"> |
| 40 | <div class="body" role="main"> |
| 41 | |
| 42 | <div class="section" id="functionality-overview"> |
| 43 | <span id="id1"></span><h1>Functionality overview</h1> |
| 44 | <p>This section provides a high-level overview of the functionality provided by the |
| 45 | interface defined in this specification. Refer to the <a class="reference internal" href="../api/library/index.html#api-reference"><span class="std std-ref">API definition</span></a> for a detailed description.</p> |
| 46 | <p><a class="reference internal" href="../appendix/history.html#future"><span class="std std-ref">Future additions</span></a> describes features that might be included in future versions of this |
| 47 | specification.</p> |
| 48 | <p>Due to the modularity of the interface, almost every part of the library is |
| 49 | optional. The only mandatory function is <a class="reference internal" href="../api/library/library.html#c.psa_crypto_init" title="psa_crypto_init"><code class="xref any c c-func docutils literal"><span class="pre">psa_crypto_init()</span></code></a>.</p> |
| 50 | <div class="section" id="library-management"> |
| 51 | <h2>Library management</h2> |
| 52 | <p>Applications must call <a class="reference internal" href="../api/library/library.html#c.psa_crypto_init" title="psa_crypto_init"><code class="xref any c c-func docutils literal"><span class="pre">psa_crypto_init()</span></code></a> to initialize the library before |
| 53 | using any other function.</p> |
| 54 | </div> |
| 55 | <div class="section" id="key-management"> |
| 56 | <h2>Key management</h2> |
| 57 | <p>Applications always access keys indirectly via an identifier, and can perform |
| 58 | operations using a key without accessing the key material. This allows keys to |
| 59 | be <em>non-extractable</em>, where an application can use a key but is not permitted to |
| 60 | obtain the key material. Non-extractable keys are bound to the device, can be |
| 61 | rate-limited and can have their usage restricted by policies.</p> |
| 62 | <p>Each key has a set of attributes that describe the key and the policy for using |
| 63 | the key. A <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_attributes_t" title="psa_key_attributes_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_attributes_t</span></code></a> object contains all of the attributes, which |
| 64 | is used when creating a key and when querying key attributes.</p> |
| 65 | <p>Each key has a <em>lifetime</em> that determines when the key material is destroyed. |
| 66 | There are two types of lifetimes: <a class="reference internal" href="#volatile-keys"><span class="std std-ref">volatile</span></a> and |
| 67 | <a class="reference internal" href="#persistent-keys"><span class="std std-ref">persistent</span></a>.</p> |
| 68 | <div class="section" id="volatile-keys"> |
| 69 | <span id="id2"></span><h3>Volatile keys</h3> |
| 70 | <p>A <em>volatile</em> key exists until it explicitly destroyed with <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> |
| 71 | or until the application terminates, which conceptually destroys all of its |
| 72 | volatile keys.</p> |
| 73 | <p>Conceptually, a volatile key is stored in RAM. Volatile keys have the |
| 74 | lifetime <a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_LIFETIME_VOLATILE" title="PSA_KEY_LIFETIME_VOLATILE"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_LIFETIME_VOLATILE</span></code></a>.</p> |
| 75 | <p>To create a volatile key:</p> |
| 76 | <ol class="arabic simple"> |
| 77 | <li>Populate a <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_attributes_t" title="psa_key_attributes_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_attributes_t</span></code></a> object with the required type, size, policy |
| 78 | and other key attributes.</li> |
| 79 | <li>Create the key with <a class="reference internal" href="../api/keys/management.html#c.psa_import_key" title="psa_import_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_import_key()</span></code></a>, <a class="reference internal" href="../api/keys/management.html#c.psa_generate_key" title="psa_generate_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_generate_key()</span></code></a>, |
| 80 | <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_output_key" title="psa_key_derivation_output_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_output_key()</span></code></a> or <a class="reference internal" href="../api/keys/management.html#c.psa_copy_key" title="psa_copy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_copy_key()</span></code></a>. If successful, these |
| 81 | functions output a transient <a class="reference internal" href="#key-ids"><span class="std std-ref">key identifier</span></a>.</li> |
| 82 | </ol> |
| 83 | <p>To destroy a volatile key, call <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> with the key identifier.</p> |
| 84 | </div> |
| 85 | <div class="section" id="persistent-keys"> |
| 86 | <span id="id3"></span><h3>Persistent keys</h3> |
| 87 | <p>A <em>persistent</em> key exists until it explicitly destroyed with <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> |
| 88 | or until it is wiped by the reset or destruction of the device.</p> |
| 89 | <p>Each persistent key has a permanent key identifier, which acts as a name for the key. |
| 90 | Within an application, the key identifier corresponds to a single key. The |
| 91 | application specifies the key identifier when the key is created and when |
| 92 | using the key.</p> |
| 93 | <p>Persistent keys can be stored in different storage areas; this is indicated |
| 94 | through different lifetime values. This specification defines a single lifetime |
| 95 | value <a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_LIFETIME_PERSISTENT" title="PSA_KEY_LIFETIME_PERSISTENT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_LIFETIME_PERSISTENT</span></code></a> which corresponds to a default storage |
| 96 | area. Implementations can define alternative lifetime values corresponding to |
| 97 | different storage areas with different retention policies, or to secure elements |
| 98 | with different security characteristics.</p> |
| 99 | <p>To create a persistent key:</p> |
| 100 | <ol class="arabic"> |
| 101 | <li><p class="first">Populate a <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_attributes_t" title="psa_key_attributes_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_attributes_t</span></code></a> object with the key’s type, size, policy |
| 102 | and other attributes.</p> |
| 103 | </li> |
| 104 | <li><p class="first">In the attributes object, set the desired lifetime and persistent identifier |
| 105 | for the key.</p> |
| 106 | </li> |
| 107 | <li><p class="first">Create the key with one of the <em>key creation functions</em>:</p> |
| 108 | <ul class="simple"> |
| 109 | <li><a class="reference internal" href="../api/keys/management.html#c.psa_import_key" title="psa_import_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_import_key()</span></code></a></li> |
| 110 | <li><a class="reference internal" href="../api/keys/management.html#c.psa_generate_key" title="psa_generate_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_generate_key()</span></code></a></li> |
| 111 | <li><a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_output_key" title="psa_key_derivation_output_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_output_key()</span></code></a></li> |
| 112 | <li><a class="reference internal" href="../api/keys/management.html#c.psa_copy_key" title="psa_copy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_copy_key()</span></code></a></li> |
| 113 | </ul> |
| 114 | <p>If successful, these functions output the <a class="reference internal" href="#key-ids"><span class="std std-ref">key identifier</span></a> |
| 115 | that was specified by the application in step 2.</p> |
| 116 | </li> |
| 117 | </ol> |
| 118 | <p>To access an existing persistent key: use the key identifier in any API that |
| 119 | requires a key.</p> |
| 120 | <p>To remove cached copies of key material for persistent keys created with the |
| 121 | <a class="reference internal" href="../api/keys/usage.html#c.PSA_KEY_USAGE_CACHE" title="PSA_KEY_USAGE_CACHE"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_USAGE_CACHE</span></code></a> policy: call <a class="reference internal" href="../api/keys/management.html#c.psa_purge_key" title="psa_purge_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_purge_key()</span></code></a> with the key identifier.</p> |
| 122 | <p>To destroy a persistent key: call <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> with the key identifier. |
| 123 | Destroying a persistent key permanently removes it from memory and storage.</p> |
| 124 | <p>The key lifetime and identifier are set when the key is created and cannot be |
| 125 | changed without destroying the key first. If the original key permits copying, |
| 126 | then the application can specify a different lifetime for the copy of the key.</p> |
| 127 | </div> |
| 128 | <div class="section" id="key-identifiers"> |
| 129 | <span id="key-ids"></span><h3>Key identifiers</h3> |
| 130 | <p>Key identifiers are integral values that act as permanent names for persistent |
| 131 | keys, or as transient references to volatile keys. Key identifiers use the |
| 132 | <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_id_t" title="psa_key_id_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_id_t</span></code></a> type, and the range of identifier values is divided as follows:</p> |
| 133 | <dl class="docutils"> |
| 134 | <dt><a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_ID_NULL" title="PSA_KEY_ID_NULL"><code class="docutils literal"><span class="pre">PSA_KEY_ID_NULL</span></code></a><code class="docutils literal"> <span class="pre">=</span> <span class="pre">0</span></code></dt> |
| 135 | <dd>Reserved as an invalid key identifier.</dd> |
| 136 | <dt><a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_ID_USER_MIN" title="PSA_KEY_ID_USER_MIN"><code class="docutils literal"><span class="pre">PSA_KEY_ID_USER_MIN</span></code></a><code class="docutils literal"> <span class="pre">-</span> </code><a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_ID_USER_MAX" title="PSA_KEY_ID_USER_MAX"><code class="docutils literal"><span class="pre">PSA_KEY_ID_USER_MAX</span></code></a></dt> |
| 137 | <dd>Applications can freely choose persistent key identifiers in this range.</dd> |
| 138 | <dt><a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_ID_VENDOR_MIN" title="PSA_KEY_ID_VENDOR_MIN"><code class="docutils literal"><span class="pre">PSA_KEY_ID_VENDOR_MIN</span></code></a><code class="docutils literal"> <span class="pre">-</span> </code><a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_ID_VENDOR_MAX" title="PSA_KEY_ID_VENDOR_MAX"><code class="docutils literal"><span class="pre">PSA_KEY_ID_VENDOR_MAX</span></code></a></dt> |
| 139 | <dd>Implementations can define additional persistent key identifiers in this |
| 140 | range, and must allocate any volatile key identifiers from this range.</dd> |
| 141 | </dl> |
| 142 | <p>Key identifiers outside these ranges are reserved for future use.</p> |
| 143 | <p>Key identifiers are output from a successful call to one of |
| 144 | the key creation functions. For persistent keys, this is the same identifier |
| 145 | as the one specified in the key attributes used to create the key. |
| 146 | The key identifier remains valid until it is invalidated by passing it to |
| 147 | <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a>. A volatile key identifier must not be used after it has been |
| 148 | invalidated.</p> |
| 149 | <p>Valid key identifiers must have distinct values within the same application. If |
| 150 | the implementation provides <a class="reference internal" href="goals.html#isolation"><span class="std std-ref">caller isolation</span></a>, then key |
| 151 | identifiers are local to each application. That is, the same key identifier in two |
| 152 | applications corresponds to two different keys.</p> |
| 153 | <p>If an invalid key identifier is provided as a parameter in any function, the |
| 154 | function will return <a class="reference internal" href="../api/library/status.html#c.PSA_ERROR_INVALID_HANDLE" title="PSA_ERROR_INVALID_HANDLE"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_ERROR_INVALID_HANDLE</span></code></a>; except for the special case of |
| 155 | calling <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="docutils literal"><span class="pre">psa_destroy_key</span></code></a><code class="docutils literal"><span class="pre">(</span></code><a class="reference internal" href="../api/keys/locations.html#c.PSA_KEY_ID_NULL" title="PSA_KEY_ID_NULL"><code class="docutils literal"><span class="pre">PSA_KEY_ID_NULL</span></code></a><code class="docutils literal"><span class="pre">)</span></code>, which has no effect and always |
| 156 | returns <a class="reference internal" href="../api/library/status.html#c.PSA_SUCCESS" title="PSA_SUCCESS"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_SUCCESS</span></code></a>.</p> |
| 157 | <p>There must be a matching call to <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> for each successful call |
| 158 | to a create a volatile key.</p> |
| 159 | <p>A call to <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> destroys the key material, and will cause any active |
| 160 | operations that are using the key to fail. Therefore an application must not |
| 161 | destroy a key while an operation using that key is in progress, unless the |
| 162 | application is prepared to handle a failure of the operation.</p> |
| 163 | </div> |
| 164 | <div class="section" id="recommendations-of-minimum-standards-for-key-management"> |
| 165 | <h3>Recommendations of minimum standards for key management</h3> |
| 166 | <p>Most implementations provide the following functions:</p> |
| 167 | <ul class="simple"> |
| 168 | <li><a class="reference internal" href="../api/keys/management.html#c.psa_import_key" title="psa_import_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_import_key()</span></code></a>. The exceptions are implementations that only give access |
| 169 | to a key or keys that are provisioned by proprietary means, and do not allow |
| 170 | the main application to use its own cryptographic material.</li> |
| 171 | <li><a class="reference internal" href="../api/keys/attributes.html#c.psa_get_key_attributes" title="psa_get_key_attributes"><code class="xref any c c-func docutils literal"><span class="pre">psa_get_key_attributes()</span></code></a> and the <code class="docutils literal"><span class="pre">psa_get_key_xxx()</span></code> accessor functions. |
| 172 | They are easy to implement, and it is difficult to write applications and to |
| 173 | diagnose issues without being able to check the metadata.</li> |
| 174 | <li><a class="reference internal" href="../api/keys/management.html#c.psa_export_public_key" title="psa_export_public_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_export_public_key()</span></code></a>. This function is usually provided if the |
| 175 | implementation supports any asymmetric algorithm, since public-key |
| 176 | cryptography often requires the delivery of a public key that is associated |
| 177 | with a protected private key.</li> |
| 178 | <li><a class="reference internal" href="../api/keys/management.html#c.psa_export_key" title="psa_export_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_export_key()</span></code></a>. However, highly constrained implementations that are |
| 179 | designed to work only with short-term keys, or only with long-term |
| 180 | non-extractable keys, do not need to provide this function.</li> |
| 181 | </ul> |
| 182 | </div> |
| 183 | </div> |
| 184 | <div class="section" id="usage-policies"> |
| 185 | <h2>Usage policies</h2> |
| 186 | <p>All keys have an associated policy that regulates which operations are permitted |
| 187 | on the key. Each key policy is a set of usage flags and a specific algorithm |
| 188 | that is permitted with the key. The policy is part of the key attributes that |
| 189 | are managed by a <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_attributes_t" title="psa_key_attributes_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_attributes_t</span></code></a> object.</p> |
| 190 | <p>The usage flags are encoded in a bitmask, which has the type |
| 191 | <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_usage_t" title="psa_key_usage_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_usage_t</span></code></a>. Four kinds of usage flag can be specified:</p> |
| 192 | <ul class="simple"> |
| 193 | <li>The extractable flag <a class="reference internal" href="../api/keys/usage.html#c.PSA_KEY_USAGE_EXPORT" title="PSA_KEY_USAGE_EXPORT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_USAGE_EXPORT</span></code></a> determines whether the key |
| 194 | material can be extracted.</li> |
| 195 | <li>The copyable flag <a class="reference internal" href="../api/keys/usage.html#c.PSA_KEY_USAGE_COPY" title="PSA_KEY_USAGE_COPY"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_USAGE_COPY</span></code></a> determines whether the key material |
| 196 | can be copied into a new key, which can have a different lifetime or a more |
| 197 | restrictive policy.</li> |
| 198 | <li>The cacheable flag <a class="reference internal" href="../api/keys/usage.html#c.PSA_KEY_USAGE_CACHE" title="PSA_KEY_USAGE_CACHE"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_USAGE_CACHE</span></code></a> determines whether the |
| 199 | implementation is permitted to retain non-essential copies of the |
| 200 | key material in RAM. This policy only applies to persistent keys. See also |
| 201 | <em><a class="reference internal" href="implementation.html#key-material"><span class="std std-ref">Managing key material</span></a></em>.</li> |
| 202 | <li>The other usage flags, for example, <a class="reference internal" href="../api/keys/usage.html#c.PSA_KEY_USAGE_ENCRYPT" title="PSA_KEY_USAGE_ENCRYPT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_USAGE_ENCRYPT</span></code></a> and <a class="reference internal" href="../api/keys/usage.html#c.PSA_KEY_USAGE_SIGN_MESSAGE" title="PSA_KEY_USAGE_SIGN_MESSAGE"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_USAGE_SIGN_MESSAGE</span></code></a>, |
| 203 | determine whether the corresponding operation is permitted on the key.</li> |
| 204 | </ul> |
| 205 | <p>In addition to the usage bitmask, a policy specifies which algorithm is |
| 206 | permitted with the key. This specification only defines policies that restrict |
| 207 | keys to a single algorithm, which is consistent with both common practice and |
| 208 | security good practice.</p> |
| 209 | <p>A highly constrained implementation might not be able to support all the policies |
| 210 | that can be expressed through this interface. If an implementation cannot create |
| 211 | a key with the required policy, it must return an appropriate error code when |
| 212 | the key is created.</p> |
| 213 | </div> |
| 214 | <div class="section" id="symmetric-cryptography"> |
| 215 | <h2>Symmetric cryptography</h2> |
| 216 | <p>This specification defines interfaces for the following types of symmetric |
| 217 | cryptographic operation:</p> |
| 218 | <ul class="simple"> |
| 219 | <li>Message digests, commonly known as hash functions.</li> |
| 220 | <li>Message authentication codes (MAC).</li> |
| 221 | <li>Symmetric ciphers.</li> |
| 222 | <li>Authenticated encryption with associated data (AEAD).</li> |
| 223 | </ul> |
| 224 | <p>For each type of symmetric cryptographic operation, the API includes:</p> |
| 225 | <ul class="simple"> |
| 226 | <li>A pair of <em>single-part</em> functions. For example, compute and verify, or |
| 227 | encrypt and decrypt.</li> |
| 228 | <li>A series of functions that permit <em>multi-part operations</em>.</li> |
| 229 | </ul> |
| 230 | <div class="section" id="single-part-functions"> |
| 231 | <h3>Single-part Functions</h3> |
| 232 | <p>Single-part functions are APIs that implement the cryptographic operation in a |
| 233 | single function call. This is the easiest API to use when all of the inputs and |
| 234 | outputs fit into the application memory.</p> |
| 235 | <p>Some use cases involve messages that are too large to be assembled in memory, or |
| 236 | require non-default configuration of the algorithm. These use cases require the |
| 237 | use of a <em><a class="reference internal" href="#multi-part-operations"><span class="std std-ref">multi-part operation</span></a></em>.</p> |
| 238 | </div> |
| 239 | <div class="section" id="multi-part-operations"> |
| 240 | <span id="id4"></span><h3>Multi-part operations</h3> |
| 241 | <p>Multi-part operations are APIs which split a single cryptographic operation into |
| 242 | a sequence of separate steps. This enables fine control over the configuration |
| 243 | of the cryptographic operation, and allows the message data to be processed in |
| 244 | fragments instead of all at once. For example, the following situations require |
| 245 | the use of a multi-part operation:</p> |
| 246 | <ul class="simple"> |
| 247 | <li>Processing messages that cannot be assembled in memory.</li> |
| 248 | <li>Using a deterministic IV for unauthenticated encryption.</li> |
| 249 | <li>Providing the IV separately for unauthenticated encryption or decryption.</li> |
| 250 | <li>Separating the AEAD authentication tag from the cipher text.</li> |
| 251 | </ul> |
| 252 | <p>Each multi-part operation defines a specific object type to maintain the state |
| 253 | of the operation. These types are implementation-defined. All multi-part |
| 254 | operations follow the same pattern of use:</p> |
| 255 | <ol class="arabic"> |
| 256 | <li><p class="first"><strong>Allocate:</strong> Allocate memory for an operation object of the appropriate |
| 257 | type. The application can use any allocation strategy: stack, heap, static, etc.</p> |
| 258 | </li> |
| 259 | <li><p class="first"><strong>Initialize:</strong> Initialize or assign the operation object by one of the |
| 260 | following methods:</p> |
| 261 | <blockquote> |
| 262 | <div><ul class="simple"> |
| 263 | <li>Set it to logical zero. This is automatic for static and global |
| 264 | variables. Explicit initialization must use the associated |
| 265 | <code class="docutils literal"><span class="pre">PSA_xxx_INIT</span></code> macro as the type is implementation-defined.</li> |
| 266 | <li>Set it to all-bits zero. This is automatic if the object was |
| 267 | allocated with <code class="docutils literal"><span class="pre">calloc()</span></code>.</li> |
| 268 | <li>Assign the value of the associated macro <code class="docutils literal"><span class="pre">PSA_xxx_INIT</span></code>.</li> |
| 269 | <li>Assign the result of calling the associated function |
| 270 | <code class="docutils literal"><span class="pre">psa_xxx_init()</span></code>.</li> |
| 271 | </ul> |
| 272 | </div></blockquote> |
| 273 | <p>The resulting object is now <em>inactive</em>.</p> |
| 274 | <p>It is an error to initialize an operation object that is in <em>active</em> or |
| 275 | <em>error</em> states. This can leak memory or other resources.</p> |
| 276 | </li> |
| 277 | <li><p class="first"><strong>Setup:</strong> Start a new multi-part operation on an <em>inactive</em> operation |
| 278 | object. Each operation object will define one or more setup functions to |
| 279 | start a specific operation.</p> |
| 280 | <p>On success, a setup function will put an operation object into an <em>active</em> |
| 281 | state. On failure, the operation object will remain <em>inactive</em>.</p> |
| 282 | </li> |
| 283 | <li><p class="first"><strong>Update:</strong> Update an <em>active</em> operation object. The update function can |
| 284 | provide additional parameters, supply data for processing or generate |
| 285 | outputs.</p> |
| 286 | <p>On success, the operation object remains <em>active</em>. On failure, the |
| 287 | operation object will enter an <em>error</em> state.</p> |
| 288 | </li> |
| 289 | <li><p class="first"><strong>Finish:</strong> To end the operation, call the applicable finishing function. |
| 290 | This will take any final inputs, produce any final outputs, and then |
| 291 | release any resources associated with the operation.</p> |
| 292 | <p>On success, the operation object returns to the <em>inactive</em> state. On |
| 293 | failure, the operation object will enter an <em>error</em> state.</p> |
| 294 | </li> |
| 295 | </ol> |
| 296 | <p>An operation can be aborted at any stage during its use by calling the |
| 297 | associated <code class="docutils literal"><span class="pre">psa_xxx_abort()</span></code> function. This will release any resources |
| 298 | associated with the operation and return the operation object to the <em>inactive</em> |
| 299 | state.</p> |
| 300 | <p>Any error that occurs to an operation while it is in an <em>active</em> state will |
| 301 | result in the operation entering an <em>error</em> state. The application must call the |
| 302 | associated <code class="docutils literal"><span class="pre">psa_xxx_abort()</span></code> function to release the operation resources and |
| 303 | return the object to the <em>inactive</em> state.</p> |
| 304 | <p>Once an operation object is returned to the <em>inactive</em> state, it can be reused |
| 305 | by calling one of the applicable setup functions again.</p> |
| 306 | <p>If a multi-part operation object is not initialized before use, the behavior is |
| 307 | undefined.</p> |
| 308 | <p>If a multi-part operation function determines that the operation object is not in |
| 309 | any valid state, it can return <a class="reference internal" href="../api/library/status.html#c.PSA_ERROR_CORRUPTION_DETECTED" title="PSA_ERROR_CORRUPTION_DETECTED"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_ERROR_CORRUPTION_DETECTED</span></code></a>.</p> |
| 310 | <p>If a multi-part operation function is called with an operation object in the |
| 311 | wrong state, the function will return <a class="reference internal" href="../api/library/status.html#c.PSA_ERROR_BAD_STATE" title="PSA_ERROR_BAD_STATE"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_ERROR_BAD_STATE</span></code></a> and the operation |
| 312 | object will enter the <em>error</em> state.</p> |
| 313 | <p>It is safe to move a multi-part operation object to a different memory location, |
| 314 | for example, using a bitwise copy, and then to use the object in the new |
| 315 | location. For example, an application can allocate an operation object on the |
| 316 | stack and return it, or the operation object can be allocated within memory |
| 317 | managed by a garbage collector. However, this does not permit the following |
| 318 | behaviors:</p> |
| 319 | <ul class="simple"> |
| 320 | <li>Moving the object while a function is being called on the object. This is |
| 321 | not safe. See also <a class="reference internal" href="conventions.html#concurrency"><span class="std std-ref">Concurrent calls</span></a>.</li> |
| 322 | <li>Working with both the original and the copied operation objects. This |
| 323 | requires cloning the operation, which is only available for hash operations |
| 324 | using <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_clone" title="psa_hash_clone"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_clone()</span></code></a>.</li> |
| 325 | </ul> |
| 326 | <p>Each type of multi-part operation can have multiple <em>active</em> states. |
| 327 | Documentation for the specific operation describes the configuration and update |
| 328 | functions, and any requirements about their usage and ordering.</p> |
| 329 | </div> |
| 330 | <div class="section" id="message-digests-hashes"> |
| 331 | <h3>Message digests (Hashes)</h3> |
| 332 | <p>The single-part hash functions are:</p> |
| 333 | <ul class="simple"> |
| 334 | <li><a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_compute" title="psa_hash_compute"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_compute()</span></code></a> to calculate the hash of a message.</li> |
| 335 | <li><a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_compare" title="psa_hash_compare"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_compare()</span></code></a> to compare the hash of a message with a reference value.</li> |
| 336 | </ul> |
| 337 | <p>The <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_operation_t" title="psa_hash_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_hash_operation_t</span></code></a> <a class="reference internal" href="#multi-part-operations"><span class="std std-ref">multi-part operation</span></a> |
| 338 | allows messages to be processed in fragments:</p> |
| 339 | <ol class="arabic simple"> |
| 340 | <li>Initialize the <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_operation_t" title="psa_hash_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_hash_operation_t</span></code></a> object to zero, or by assigning the |
| 341 | value of the associated macro <a class="reference internal" href="../api/ops/hashes.html#c.PSA_HASH_OPERATION_INIT" title="PSA_HASH_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_HASH_OPERATION_INIT</span></code></a>.</li> |
| 342 | <li>Call <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_setup" title="psa_hash_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_setup()</span></code></a> to specify the required hash algorithm, call |
| 343 | <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_clone" title="psa_hash_clone"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_clone()</span></code></a> to duplicate the state of <em>active</em> <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_operation_t" title="psa_hash_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_hash_operation_t</span></code></a> |
| 344 | object, or call <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_resume" title="psa_hash_resume"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_resume()</span></code></a> to restart a hash operation with the |
| 345 | output from a previously suspended hash operation.</li> |
| 346 | <li>Call the <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_update" title="psa_hash_update"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_update()</span></code></a> function on successive chunks of the message.</li> |
| 347 | <li>At the end of the message, call the required finishing function:<ul> |
| 348 | <li>To suspend the hash operation and extract a hash suspend state, |
| 349 | call <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_suspend" title="psa_hash_suspend"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_suspend()</span></code></a>. The output state can subsequently be used |
| 350 | to resume the hash operation.</li> |
| 351 | <li>To calculate the digest of a message, call <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_finish" title="psa_hash_finish"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_finish()</span></code></a>.</li> |
| 352 | <li>To verify the digest of a message against a reference value, call |
| 353 | <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_verify" title="psa_hash_verify"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_verify()</span></code></a>.</li> |
| 354 | </ul> |
| 355 | </li> |
| 356 | </ol> |
| 357 | <p>To abort the operation or recover from an error, call <a class="reference internal" href="../api/ops/hashes.html#c.psa_hash_abort" title="psa_hash_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_hash_abort()</span></code></a>.</p> |
| 358 | </div> |
| 359 | <div class="section" id="message-authentication-codes-macs"> |
| 360 | <h3>Message authentication codes (MACs)</h3> |
| 361 | <p>The single-part MAC functions are:</p> |
| 362 | <ul class="simple"> |
| 363 | <li><a class="reference internal" href="../api/ops/macs.html#c.psa_mac_compute" title="psa_mac_compute"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_compute()</span></code></a> to calculate the MAC of a message.</li> |
| 364 | <li><a class="reference internal" href="../api/ops/macs.html#c.psa_mac_verify" title="psa_mac_verify"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_verify()</span></code></a> to compare the MAC of a message with a reference value.</li> |
| 365 | </ul> |
| 366 | <p>The <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_operation_t" title="psa_mac_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_mac_operation_t</span></code></a> <a class="reference internal" href="#multi-part-operations"><span class="std std-ref">multi-part operation</span></a> |
| 367 | allows messages to be processed in fragments:</p> |
| 368 | <ol class="arabic simple"> |
| 369 | <li>Initialize the <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_operation_t" title="psa_mac_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_mac_operation_t</span></code></a> object to zero, or by assigning the |
| 370 | value of the associated macro <a class="reference internal" href="../api/ops/macs.html#c.PSA_MAC_OPERATION_INIT" title="PSA_MAC_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_MAC_OPERATION_INIT</span></code></a>.</li> |
| 371 | <li>Call <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_sign_setup" title="psa_mac_sign_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_sign_setup()</span></code></a> or <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_verify_setup" title="psa_mac_verify_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_verify_setup()</span></code></a> to specify the |
| 372 | algorithm and key.</li> |
| 373 | <li>Call the <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_update" title="psa_mac_update"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_update()</span></code></a> function on successive chunks of the message.</li> |
| 374 | <li>At the end of the message, call the required finishing function:<ul> |
| 375 | <li>To calculate the MAC of the message, call <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_sign_finish" title="psa_mac_sign_finish"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_sign_finish()</span></code></a>.</li> |
| 376 | <li>To verify the MAC of the message against a reference value, call |
| 377 | <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_verify_finish" title="psa_mac_verify_finish"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_verify_finish()</span></code></a>.</li> |
| 378 | </ul> |
| 379 | </li> |
| 380 | </ol> |
| 381 | <p>To abort the operation or recover from an error, call <a class="reference internal" href="../api/ops/macs.html#c.psa_mac_abort" title="psa_mac_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_mac_abort()</span></code></a>.</p> |
| 382 | </div> |
| 383 | <div class="section" id="encryption-and-decryption"> |
| 384 | <h3>Encryption and decryption</h3> |
| 385 | <div class="admonition note"> |
| 386 | <p class="first admonition-title">Note</p> |
| 387 | <p class="last">The unauthenticated cipher API is provided to implement legacy protocols and |
| 388 | for use cases where the data integrity and authenticity is guaranteed by |
| 389 | non-cryptographic means. It is recommended that newer protocols use |
| 390 | <em><a class="reference internal" href="#func-aead"><span class="std std-ref">Authenticated encryption (AEAD)</span></a></em>.</p> |
| 391 | </div> |
| 392 | <p>The single-part functions for encrypting or decrypting a message using an |
| 393 | unauthenticated symmetric cipher are:</p> |
| 394 | <ul class="simple"> |
| 395 | <li><a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_encrypt" title="psa_cipher_encrypt"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_encrypt()</span></code></a> to encrypt a message using an unauthenticated symmetric |
| 396 | cipher. The encryption function generates a random IV. Use the multi-part API |
| 397 | to provide a deterministic IV: this is not secure in general, but |
| 398 | can be secure in some conditions that depend on the algorithm.</li> |
| 399 | <li><a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_decrypt" title="psa_cipher_decrypt"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_decrypt()</span></code></a> to decrypt a message using an unauthenticated symmetric |
| 400 | cipher.</li> |
| 401 | </ul> |
| 402 | <p>The <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_operation_t" title="psa_cipher_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_cipher_operation_t</span></code></a> <a class="reference internal" href="#multi-part-operations"><span class="std std-ref">multi-part operation</span></a> |
| 403 | permits alternative initialization parameters and allows messages to be |
| 404 | processed in fragments:</p> |
| 405 | <ol class="arabic simple"> |
| 406 | <li>Initialize the <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_operation_t" title="psa_cipher_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_cipher_operation_t</span></code></a> object to zero, or by assigning the |
| 407 | value of the associated macro <a class="reference internal" href="../api/ops/ciphers.html#c.PSA_CIPHER_OPERATION_INIT" title="PSA_CIPHER_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_CIPHER_OPERATION_INIT</span></code></a>.</li> |
| 408 | <li>Call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_encrypt_setup" title="psa_cipher_encrypt_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_encrypt_setup()</span></code></a> or <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_decrypt_setup" title="psa_cipher_decrypt_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_decrypt_setup()</span></code></a> to specify the |
| 409 | algorithm and key.</li> |
| 410 | <li>Provide additional parameters:<ul> |
| 411 | <li>When encrypting data, generate or set an initialization vector (IV), |
| 412 | nonce, or similar initial value such as an initial counter value. To |
| 413 | generate a random IV, which is recommended in most protocols, call |
| 414 | <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_generate_iv" title="psa_cipher_generate_iv"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_generate_iv()</span></code></a>. To set the IV, call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_set_iv" title="psa_cipher_set_iv"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_set_iv()</span></code></a>.</li> |
| 415 | <li>When decrypting, set the IV or nonce. To set the IV, call |
| 416 | <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_set_iv" title="psa_cipher_set_iv"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_set_iv()</span></code></a>.</li> |
| 417 | </ul> |
| 418 | </li> |
| 419 | <li>Call the <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_update" title="psa_cipher_update"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_update()</span></code></a> function on successive chunks of the message.</li> |
| 420 | <li>Call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_finish" title="psa_cipher_finish"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_finish()</span></code></a> to complete the operation and return any final |
| 421 | output.</li> |
| 422 | </ol> |
| 423 | <p>To abort the operation or recover from an error, call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_abort" title="psa_cipher_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_abort()</span></code></a>.</p> |
| 424 | </div> |
| 425 | <div class="section" id="authenticated-encryption-aead"> |
| 426 | <span id="func-aead"></span><h3>Authenticated encryption (AEAD)</h3> |
| 427 | <p>The single-part AEAD functions are:</p> |
| 428 | <ul class="simple"> |
| 429 | <li><a class="reference internal" href="../api/ops/aead.html#c.psa_aead_encrypt" title="psa_aead_encrypt"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_encrypt()</span></code></a> to encrypt a message using an authenticated symmetric |
| 430 | cipher.</li> |
| 431 | <li><a class="reference internal" href="../api/ops/aead.html#c.psa_aead_decrypt" title="psa_aead_decrypt"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_decrypt()</span></code></a> to decrypt a message using an authenticated symmetric |
| 432 | cipher.</li> |
| 433 | </ul> |
| 434 | <p>These functions follow the interface recommended by <a class="reference external" href="https://tools.ietf.org/html/rfc5116.html">RFC 5116</a>.</p> |
| 435 | <p>The encryption function requires a nonce to be provided. To generate a random |
| 436 | nonce, either call <a class="reference internal" href="../api/ops/rng.html#c.psa_generate_random" title="psa_generate_random"><code class="xref any c c-func docutils literal"><span class="pre">psa_generate_random()</span></code></a> or use the AEAD multi-part API.</p> |
| 437 | <p>The <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_operation_t" title="psa_aead_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_aead_operation_t</span></code></a> <a class="reference internal" href="#multi-part-operations"><span class="std std-ref">multi-part operation</span></a> |
| 438 | permits alternative initialization parameters and allows messages to be |
| 439 | processed in fragments:</p> |
| 440 | <ol class="arabic simple"> |
| 441 | <li>Initialize the <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_operation_t" title="psa_aead_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_aead_operation_t</span></code></a> object to zero, or by assigning the |
| 442 | value of the associated macro <a class="reference internal" href="../api/ops/aead.html#c.PSA_AEAD_OPERATION_INIT" title="PSA_AEAD_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_AEAD_OPERATION_INIT</span></code></a>.</li> |
| 443 | <li>Call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_encrypt_setup" title="psa_aead_encrypt_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_encrypt_setup()</span></code></a> or <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_decrypt_setup" title="psa_aead_decrypt_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_decrypt_setup()</span></code></a> to specify the |
| 444 | algorithm and key.</li> |
| 445 | <li>Provide additional parameters:<ul> |
| 446 | <li>If the algorithm requires it, call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_set_lengths" title="psa_aead_set_lengths"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_set_lengths()</span></code></a> to specify the |
| 447 | length of the non-encrypted and encrypted inputs to the operation.</li> |
| 448 | <li>When encrypting, call either <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_generate_nonce" title="psa_aead_generate_nonce"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_generate_nonce()</span></code></a> or |
| 449 | <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_set_nonce" title="psa_aead_set_nonce"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_set_nonce()</span></code></a> to generate or set the nonce.</li> |
| 450 | <li>When decrypting, call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_set_nonce" title="psa_aead_set_nonce"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_set_nonce()</span></code></a> to set the nonce.</li> |
| 451 | </ul> |
| 452 | </li> |
| 453 | <li>Call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_update_ad" title="psa_aead_update_ad"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_update_ad()</span></code></a> zero or more times with fragments of the |
| 454 | non-encrypted additional data.</li> |
| 455 | <li>Call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_update" title="psa_aead_update"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_update()</span></code></a> zero or more times with fragments of the plaintext |
| 456 | or ciphertext to encrypt or decrypt.</li> |
| 457 | <li>At the end of the message, call the required finishing function:<ul> |
| 458 | <li>To complete an encryption operation, call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_finish" title="psa_aead_finish"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_finish()</span></code></a> to compute |
| 459 | and return authentication tag.</li> |
| 460 | <li>To complete a decryption operation, call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_verify" title="psa_aead_verify"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_verify()</span></code></a> to |
| 461 | compute the authentication tag and verify it against a reference value.</li> |
| 462 | </ul> |
| 463 | </li> |
| 464 | </ol> |
| 465 | <p>To abort the operation or recover from an error, call <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_abort" title="psa_aead_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_abort()</span></code></a>.</p> |
| 466 | <p>Having a multi-part interface to authenticated encryption raises specific issues.</p> |
| 467 | <p>Multi-part authenticated decryption produces partial results that are not |
| 468 | authenticated. Applications must not use or expose partial results of |
| 469 | authenticated decryption until <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_verify" title="psa_aead_verify"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_verify()</span></code></a> has returned a success |
| 470 | status and must destroy all partial results without revealing them if |
| 471 | <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_verify" title="psa_aead_verify"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_verify()</span></code></a> returns a failure status. Revealing partial results, either directly or indirectly through the application’s behavior, can compromise the |
| 472 | confidentiality of all inputs that are encrypted with the same key.</p> |
| 473 | <p>For encryption, some common algorithms cannot be processed in a streaming |
| 474 | fashion. For SIV mode, the whole plaintext must be known before the encryption |
| 475 | can start; the multi-part AEAD API is not meant to be usable with SIV mode. For |
| 476 | CCM mode, the length of the plaintext must be known before the encryption can |
| 477 | start; the application can call the function <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_set_lengths" title="psa_aead_set_lengths"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_set_lengths()</span></code></a> to provide |
| 478 | these lengths before providing input.</p> |
| 479 | </div> |
| 480 | <div class="section" id="key-derivation"> |
| 481 | <span id="id5"></span><h3>Key derivation</h3> |
| 482 | <p>A key derivation encodes a deterministic method to generate a finite stream of |
| 483 | bytes. This data stream is computed by the cryptoprocessor and extracted in |
| 484 | chunks. If two key derivation operations are constructed with the same |
| 485 | parameters, then they produce the same output.</p> |
| 486 | <p>A key derivation consists of two phases:</p> |
| 487 | <ol class="arabic simple"> |
| 488 | <li>Input collection. This is sometimes known as <em>extraction</em>: the operation |
| 489 | “extracts” information from the inputs to generate a pseudorandom |
| 490 | intermediate secret value.</li> |
| 491 | <li>Output generation. This is sometimes known as <em>expansion</em>: the operation |
| 492 | “expands” the intermediate secret value to the desired output length.</li> |
| 493 | </ol> |
| 494 | <p>The specification defines a <a class="reference internal" href="#multi-part-operations"><span class="std std-ref">multi-part operation</span></a> |
| 495 | API for key derivation that allows for multiple key and non-key outputs to be |
| 496 | extracted from a single derivation operation object.</p> |
| 497 | <p>In an implementation with <a class="reference internal" href="goals.html#isolation"><span class="std std-ref">isolation</span></a>, the intermediate |
| 498 | state of the key derivation is not visible to the caller, and if an output of |
| 499 | the derivation is a non-exportable key, then this key cannot be recovered |
| 500 | outside the isolation boundary.</p> |
| 501 | <p>Applications use the <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_operation_t" title="psa_key_derivation_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_derivation_operation_t</span></code></a> type to create key |
| 502 | derivation operations. The operation object is used as follows:</p> |
| 503 | <ol class="arabic simple"> |
| 504 | <li>Initialize a <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_operation_t" title="psa_key_derivation_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_derivation_operation_t</span></code></a> object to zero or to |
| 505 | <a class="reference internal" href="../api/ops/kdf.html#c.PSA_KEY_DERIVATION_OPERATION_INIT" title="PSA_KEY_DERIVATION_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_DERIVATION_OPERATION_INIT</span></code></a>.</li> |
| 506 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_setup" title="psa_key_derivation_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_setup()</span></code></a> to select a key derivation algorithm.</li> |
| 507 | <li>Call the functions <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_input_bytes" title="psa_key_derivation_input_bytes"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_input_bytes()</span></code></a> and |
| 508 | <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_input_key" title="psa_key_derivation_input_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_input_key()</span></code></a>, or <a class="reference internal" href="../api/ops/ka.html#c.psa_key_derivation_key_agreement" title="psa_key_derivation_key_agreement"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_key_agreement()</span></code></a> to |
| 509 | provide the inputs to the key derivation algorithm. Many key derivation |
| 510 | algorithms take multiple inputs; the <code class="docutils literal"><span class="pre">step</span></code> parameter to these functions |
| 511 | indicates which input is being provided. The documentation for each key |
| 512 | derivation algorithm describes the expected inputs for that algorithm and |
| 513 | in what order to pass them.</li> |
| 514 | <li>Optionally, call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_set_capacity" title="psa_key_derivation_set_capacity"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_set_capacity()</span></code></a> to set a limit on the |
| 515 | amount of data that can be output from the key derivation operation.</li> |
| 516 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_output_key" title="psa_key_derivation_output_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_output_key()</span></code></a> to create a derived key, or |
| 517 | <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_output_bytes" title="psa_key_derivation_output_bytes"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_output_bytes()</span></code></a> to export the derived data. These |
| 518 | functions can be called multiple times to read successive output from the key |
| 519 | derivation, until the stream is exhausted when its capacity has been reached.</li> |
| 520 | <li>Key derivation does not finish in the same way as other multi-part |
| 521 | operations. Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_abort" title="psa_key_derivation_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_abort()</span></code></a> to release the key derivation |
| 522 | operation memory when the object is no longer required.</li> |
| 523 | </ol> |
| 524 | <p>To recover from an error, call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_abort" title="psa_key_derivation_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_abort()</span></code></a> to release the key |
| 525 | derivation operation memory.</p> |
| 526 | <p>A key derivation operation cannot be rewound. Once a part of the stream has been |
| 527 | output, it cannot be output again. This ensures that the same part of the output |
| 528 | will not be used for different purposes.</p> |
| 529 | </div> |
| 530 | <div class="section" id="example-of-the-symmetric-cryptography-api"> |
| 531 | <h3>Example of the symmetric cryptography API</h3> |
| 532 | <p>Here is an example of a use case where a master key is used to generate both a |
| 533 | message encryption key and an IV for the encryption, and the derived key and IV |
| 534 | are then used to encrypt a message.</p> |
| 535 | <ol class="arabic simple"> |
| 536 | <li>Derive the message encryption material from the master key.<ol class="arabic"> |
| 537 | <li>Initialize a <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_operation_t" title="psa_key_derivation_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_derivation_operation_t</span></code></a> object to zero or to |
| 538 | <a class="reference internal" href="../api/ops/kdf.html#c.PSA_KEY_DERIVATION_OPERATION_INIT" title="PSA_KEY_DERIVATION_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_DERIVATION_OPERATION_INIT</span></code></a>.</li> |
| 539 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_setup" title="psa_key_derivation_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_setup()</span></code></a> with <a class="reference internal" href="../api/ops/kdf.html#c.PSA_ALG_HKDF" title="PSA_ALG_HKDF"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_ALG_HKDF</span></code></a> as the algorithm.</li> |
| 540 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_input_key" title="psa_key_derivation_input_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_input_key()</span></code></a> with the step |
| 541 | <a class="reference internal" href="../api/ops/kdf.html#c.PSA_KEY_DERIVATION_INPUT_SECRET" title="PSA_KEY_DERIVATION_INPUT_SECRET"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_DERIVATION_INPUT_SECRET</span></code></a> and the master key.</li> |
| 542 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_input_bytes" title="psa_key_derivation_input_bytes"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_input_bytes()</span></code></a> with the step |
| 543 | <a class="reference internal" href="../api/ops/kdf.html#c.PSA_KEY_DERIVATION_INPUT_INFO" title="PSA_KEY_DERIVATION_INPUT_INFO"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_KEY_DERIVATION_INPUT_INFO</span></code></a> and a public value that uniquely |
| 544 | identifies the message.</li> |
| 545 | <li>Populate a <a class="reference internal" href="../api/keys/attributes.html#c.psa_key_attributes_t" title="psa_key_attributes_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_key_attributes_t</span></code></a> object with the derived message |
| 546 | encryption key’s attributes.</li> |
| 547 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_output_key" title="psa_key_derivation_output_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_output_key()</span></code></a> to create the derived message key.</li> |
| 548 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_output_bytes" title="psa_key_derivation_output_bytes"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_output_bytes()</span></code></a> to generate the derived IV.</li> |
| 549 | <li>Call <a class="reference internal" href="../api/ops/kdf.html#c.psa_key_derivation_abort" title="psa_key_derivation_abort"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_abort()</span></code></a> to release the key derivation operation |
| 550 | memory.</li> |
| 551 | </ol> |
| 552 | </li> |
| 553 | <li>Encrypt the message with the derived material.<ol class="arabic"> |
| 554 | <li>Initialize a <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_operation_t" title="psa_cipher_operation_t"><code class="xref any c c-type docutils literal"><span class="pre">psa_cipher_operation_t</span></code></a> object to zero or to |
| 555 | <a class="reference internal" href="../api/ops/ciphers.html#c.PSA_CIPHER_OPERATION_INIT" title="PSA_CIPHER_OPERATION_INIT"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_CIPHER_OPERATION_INIT</span></code></a>.</li> |
| 556 | <li>Call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_encrypt_setup" title="psa_cipher_encrypt_setup"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_encrypt_setup()</span></code></a> with the derived message encryption key.</li> |
| 557 | <li>Call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_set_iv" title="psa_cipher_set_iv"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_set_iv()</span></code></a> using the derived IV retrieved above.</li> |
| 558 | <li>Call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_update" title="psa_cipher_update"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_update()</span></code></a> one or more times to encrypt the message.</li> |
| 559 | <li>Call <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_finish" title="psa_cipher_finish"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_finish()</span></code></a> at the end of the message.</li> |
| 560 | </ol> |
| 561 | </li> |
| 562 | <li>Call <a class="reference internal" href="../api/keys/management.html#c.psa_destroy_key" title="psa_destroy_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_destroy_key()</span></code></a> to clear the generated key.</li> |
| 563 | </ol> |
| 564 | </div> |
| 565 | </div> |
| 566 | <div class="section" id="asymmetric-cryptography"> |
| 567 | <h2>Asymmetric cryptography</h2> |
| 568 | <p>This specification defines functions for asymmetric cryptography, including |
| 569 | asymmetric encryption, asymmetric signature, and two-way key agreement.</p> |
| 570 | <div class="section" id="asymmetric-encryption"> |
| 571 | <h3>Asymmetric encryption</h3> |
| 572 | <p>Asymmetric encryption is provided through the functions |
| 573 | <a class="reference internal" href="../api/ops/pke.html#c.psa_asymmetric_encrypt" title="psa_asymmetric_encrypt"><code class="xref any c c-func docutils literal"><span class="pre">psa_asymmetric_encrypt()</span></code></a> and <a class="reference internal" href="../api/ops/pke.html#c.psa_asymmetric_decrypt" title="psa_asymmetric_decrypt"><code class="xref any c c-func docutils literal"><span class="pre">psa_asymmetric_decrypt()</span></code></a>.</p> |
| 574 | </div> |
| 575 | <div class="section" id="hash-and-sign"> |
| 576 | <h3>Hash-and-sign</h3> |
| 577 | <p>The signature and verification functions <a class="reference internal" href="../api/ops/sign.html#c.psa_sign_message" title="psa_sign_message"><code class="xref any c c-func docutils literal"><span class="pre">psa_sign_message()</span></code></a> and |
| 578 | <a class="reference internal" href="../api/ops/sign.html#c.psa_verify_message" title="psa_verify_message"><code class="xref any c c-func docutils literal"><span class="pre">psa_verify_message()</span></code></a> take a message as one of their inputs and perform a |
| 579 | hash-and-sign algorithm.</p> |
| 580 | <p>The functions <a class="reference internal" href="../api/ops/sign.html#c.psa_sign_hash" title="psa_sign_hash"><code class="xref any c c-func docutils literal"><span class="pre">psa_sign_hash()</span></code></a> and <a class="reference internal" href="../api/ops/sign.html#c.psa_verify_hash" title="psa_verify_hash"><code class="xref any c c-func docutils literal"><span class="pre">psa_verify_hash()</span></code></a> take a message hash as |
| 581 | one of their inputs. This is useful for signing pre-computed hashes, or for |
| 582 | implementing hash-and-sign using a <a class="reference internal" href="../api/ops/hashes.html#hash-mp"><span class="std std-ref">multi-part hash operation</span></a> |
| 583 | before signing the resulting hash. To determine which |
| 584 | hash algorithm to use, call the macro <a class="reference internal" href="../api/keys/algorithms.html#c.PSA_ALG_GET_HASH" title="PSA_ALG_GET_HASH"><code class="xref any c c-macro docutils literal"><span class="pre">PSA_ALG_GET_HASH()</span></code></a> on the |
| 585 | corresponding signature algorithm.</p> |
| 586 | <p>Some hash-and-sign algorithms add padding to the message hash before completing |
| 587 | the signing operation. The format of the padding that is used depends on the |
| 588 | algorithm used to construct the signature.</p> |
| 589 | </div> |
| 590 | <div class="section" id="key-agreement"> |
| 591 | <h3>Key agreement</h3> |
| 592 | <p>This specification defines two functions for a Diffie-Hellman-style key |
| 593 | agreement where each party combines its own private key with the peer’s public |
| 594 | key.</p> |
| 595 | <p>The recommended approach is to use a <a class="reference internal" href="#key-derivation"><span class="std std-ref">key derivation |
| 596 | operation</span></a> with the <a class="reference internal" href="../api/ops/ka.html#c.psa_key_derivation_key_agreement" title="psa_key_derivation_key_agreement"><code class="xref any c c-func docutils literal"><span class="pre">psa_key_derivation_key_agreement()</span></code></a> |
| 597 | input function, which calculates a shared secret for the key derivation |
| 598 | function.</p> |
| 599 | <p>Where an application needs direct access to the shared secret, it can call |
| 600 | <a class="reference internal" href="../api/ops/ka.html#c.psa_raw_key_agreement" title="psa_raw_key_agreement"><code class="xref any c c-func docutils literal"><span class="pre">psa_raw_key_agreement()</span></code></a> instead. Note that in general the shared secret is not |
| 601 | directly suitable for use as a key because it is biased.</p> |
| 602 | </div> |
| 603 | </div> |
| 604 | <div class="section" id="randomness-and-key-generation"> |
| 605 | <h2>Randomness and key generation</h2> |
| 606 | <p>We strongly recommended that implementations include a random generator, |
| 607 | consisting of a cryptographically secure pseudo-random generator (CSPRNG), which |
| 608 | is adequately seeded with a cryptographic-quality hardware entropy source, |
| 609 | commonly referred to as a true random number generator (TRNG). Constrained |
| 610 | implementations can omit the random generation functionality if they do not |
| 611 | implement any algorithm that requires randomness internally, and they do not |
| 612 | provide a key generation functionality. For example, a special-purpose component |
| 613 | for signature verification can omit this.</p> |
| 614 | <p>It is recommended that applications use <a class="reference internal" href="../api/keys/management.html#c.psa_generate_key" title="psa_generate_key"><code class="xref any c c-func docutils literal"><span class="pre">psa_generate_key()</span></code></a>, |
| 615 | <a class="reference internal" href="../api/ops/ciphers.html#c.psa_cipher_generate_iv" title="psa_cipher_generate_iv"><code class="xref any c c-func docutils literal"><span class="pre">psa_cipher_generate_iv()</span></code></a> or <a class="reference internal" href="../api/ops/aead.html#c.psa_aead_generate_nonce" title="psa_aead_generate_nonce"><code class="xref any c c-func docutils literal"><span class="pre">psa_aead_generate_nonce()</span></code></a> to generate |
| 616 | suitably-formatted random data, as applicable. In addition, the API includes a |
| 617 | function <a class="reference internal" href="../api/ops/rng.html#c.psa_generate_random" title="psa_generate_random"><code class="xref any c c-func docutils literal"><span class="pre">psa_generate_random()</span></code></a> to generate and extract arbitrary random data.</p> |
| 618 | </div> |
| 619 | </div> |
| 620 | |
| 621 | |
| 622 | </div> |
| 623 | </div> |
| 624 | </div> |
| 625 | <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> |
| 626 | <div class="sphinxsidebarwrapper"> |
| 627 | <h3><a href="../index.html">Table Of Contents</a></h3> |
| 628 | <ul> |
| 629 | <li><a class="reference internal" href="#">Functionality overview</a><ul> |
| 630 | <li><a class="reference internal" href="#library-management">Library management</a></li> |
| 631 | <li><a class="reference internal" href="#key-management">Key management</a><ul> |
| 632 | <li><a class="reference internal" href="#volatile-keys">Volatile keys</a></li> |
| 633 | <li><a class="reference internal" href="#persistent-keys">Persistent keys</a></li> |
| 634 | <li><a class="reference internal" href="#key-identifiers">Key identifiers</a></li> |
| 635 | <li><a class="reference internal" href="#recommendations-of-minimum-standards-for-key-management">Recommendations of minimum standards for key management</a></li> |
| 636 | </ul> |
| 637 | </li> |
| 638 | <li><a class="reference internal" href="#usage-policies">Usage policies</a></li> |
| 639 | <li><a class="reference internal" href="#symmetric-cryptography">Symmetric cryptography</a><ul> |
| 640 | <li><a class="reference internal" href="#single-part-functions">Single-part Functions</a></li> |
| 641 | <li><a class="reference internal" href="#multi-part-operations">Multi-part operations</a></li> |
| 642 | <li><a class="reference internal" href="#message-digests-hashes">Message digests (Hashes)</a></li> |
| 643 | <li><a class="reference internal" href="#message-authentication-codes-macs">Message authentication codes (MACs)</a></li> |
| 644 | <li><a class="reference internal" href="#encryption-and-decryption">Encryption and decryption</a></li> |
| 645 | <li><a class="reference internal" href="#authenticated-encryption-aead">Authenticated encryption (AEAD)</a></li> |
| 646 | <li><a class="reference internal" href="#key-derivation">Key derivation</a></li> |
| 647 | <li><a class="reference internal" href="#example-of-the-symmetric-cryptography-api">Example of the symmetric cryptography API</a></li> |
| 648 | </ul> |
| 649 | </li> |
| 650 | <li><a class="reference internal" href="#asymmetric-cryptography">Asymmetric cryptography</a><ul> |
| 651 | <li><a class="reference internal" href="#asymmetric-encryption">Asymmetric encryption</a></li> |
| 652 | <li><a class="reference internal" href="#hash-and-sign">Hash-and-sign</a></li> |
| 653 | <li><a class="reference internal" href="#key-agreement">Key agreement</a></li> |
| 654 | </ul> |
| 655 | </li> |
| 656 | <li><a class="reference internal" href="#randomness-and-key-generation">Randomness and key generation</a></li> |
| 657 | </ul> |
| 658 | </li> |
| 659 | </ul> |
| 660 | <div class="relations"> |
| 661 | <h3>Related Topics</h3> |
| 662 | <ul> |
| 663 | <li><a href="../index.html">Documentation overview</a><ul> |
| 664 | <li>Previous: <a href="goals.html" title="previous chapter">Design goals</a></li> |
| 665 | <li>Next: <a href="sample-arch.html" title="next chapter">Sample architectures</a></li> |
| 666 | </ul></li> |
| 667 | </ul> |
| 668 | </div> |
| 669 | <div role="note" aria-label="source link"> |
| 670 | <h3>This Page</h3> |
| 671 | <ul class="this-page-menu"> |
| 672 | <li><a href="../_sources/overview/functionality.rst.txt" |
| 673 | rel="nofollow">Show Source</a></li> |
| 674 | </ul> |
| 675 | </div> |
| 676 | <div id="searchbox" style="display: none" role="search"> |
| 677 | <h3>Quick search</h3> |
| 678 | <form class="search" action="../search.html" method="get"> |
| 679 | <div><input type="text" name="q" /></div> |
| 680 | <div><input type="submit" value="Go" /></div> |
| 681 | <input type="hidden" name="check_keywords" value="yes" /> |
| 682 | <input type="hidden" name="area" value="default" /> |
| 683 | </form> |
| 684 | </div> |
| 685 | <script type="text/javascript">$('#searchbox').show(0);</script> |
| 686 | </div> |
| 687 | </div> |
| 688 | <div class="clearer"></div> |
| 689 | </div> |
| 690 | <div class="footer"> |
| 691 | © 2019-2020, Arm Limited or its affiliates. All rights reserved. |
| 692 | |
| 693 | | |
| 694 | Powered by <a href="http://sphinx-doc.org/">Sphinx 1.6.7</a> |
| 695 | & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.8</a> |
| 696 | |
| 697 | | |
| 698 | <a href="../_sources/overview/functionality.rst.txt" |
| 699 | rel="nofollow">Page source</a> |
| 700 | </div> |
| 701 | |
| 702 | |
| 703 | |
| 704 | |
| 705 | </body> |
| 706 | </html> |