Gilles Peskine | 6c723a2 | 2020-04-17 16:57:52 +0200 | [diff] [blame^] | 1 | .. _implementation-considerations: |
| 2 | |
| 3 | Implementation considerations |
| 4 | ----------------------------- |
| 5 | |
| 6 | Implementation-specific aspects of the interface |
| 7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 8 | |
| 9 | Implementation profile |
| 10 | ^^^^^^^^^^^^^^^^^^^^^^ |
| 11 | |
| 12 | Implementations can implement a subset of the API and a subset of the available |
| 13 | algorithms. The implemented subset is known as the implementation’s profile. The |
| 14 | documentation for each implementation must describe the profile that it |
| 15 | implements. This specification’s companion documents also define a number of |
| 16 | standard profiles. |
| 17 | |
| 18 | .. _implementation-defined-type: |
| 19 | |
| 20 | Implementation-specific types |
| 21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 22 | |
| 23 | This specification defines a number of implementation-specific types, which |
| 24 | represent objects whose content depends on the implementation. These are defined |
| 25 | as C ``typedef`` types in this specification, with a comment |
| 26 | :code:`/* implementation-defined type */` in place of the underlying type |
| 27 | definition. For some types the specification constrains the type, for example, |
| 28 | by requiring that the type is a ``struct``, or that it is convertible to and |
| 29 | from an unsigned integer. In the implementation's version of **psa/crypto.h**, |
| 30 | these types need to be defined as complete C types so that objects of these |
| 31 | types can be instantiated by application code. |
| 32 | |
| 33 | Applications that rely on the implementation specific definition of any of these |
| 34 | types might not be portable to other implementations of this specification. |
| 35 | |
| 36 | .. _implementation-specific-macro: |
| 37 | |
| 38 | Implementation-specific macros |
| 39 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 40 | |
| 41 | Some macro constants and function-like macros are precisely defined by this |
| 42 | specification. The use of an exact definition is essential if the definition can |
| 43 | appear in more than one header file within a compilation. |
| 44 | |
| 45 | Other macros that are defined by this specification have a macro body that is |
| 46 | implementation-specific. The description of an implementation-specific macro can |
| 47 | optionally specify each of the following requirements: |
| 48 | |
| 49 | * Input domains: the macro must be valid for arguments within the input domain. |
| 50 | * A return type: the macro result must be compatible with this type. |
| 51 | * Output range: the macro result must lie in the output range. |
| 52 | * Computed value: A precise mapping of valid input to output values. |
| 53 | |
| 54 | Each implementation-specific macro is in one of following categories: |
| 55 | |
| 56 | .. _specification-defined-value: |
| 57 | |
| 58 | *Specification-defined value* |
| 59 | |
| 60 | The result type and computed value of the macro expression is defined by |
| 61 | this specification, but the definition of the macro body is provided by the |
| 62 | implementation. |
| 63 | |
| 64 | These macros are indicated in this specification using the comment |
| 65 | :code:`/* specification-defined value */`. |
| 66 | |
| 67 | .. TODO!! |
| 68 | Change this text when we have provided pseudo-code implementations of |
| 69 | all the relevant macro expressions. |
| 70 | |
| 71 | For function-like macros with specification-defined values: |
| 72 | |
| 73 | * Example implementations are provided in an appendix to this specification. |
| 74 | See :title:`appendix-specdef-values`. |
| 75 | |
| 76 | * The expected computation for valid and supported input arguments will be |
| 77 | defined as pseudo-code in a future version of this specification. |
| 78 | |
| 79 | .. _implementation-defined-value: |
| 80 | |
| 81 | *Implementation-defined value* |
| 82 | |
| 83 | The value of the macro expression is implementation-defined. |
| 84 | |
| 85 | For some macros, the computed value is derived from the specification of one |
| 86 | or more cryptographic algorithms. In these cases, the result must exactly |
| 87 | match the value in those external specifications. |
| 88 | |
| 89 | These macros are indicated in this specification using the comment |
| 90 | :code:`/* implementation-defined value */`. |
| 91 | |
| 92 | Some of these macros compute a result based on an algorithm or key type. |
| 93 | If an implementation defines vendor-specific algorithms or |
| 94 | key types, then it must provide an implementation for such macros that takes all |
| 95 | relevant algorithms and types into account. Conversely, an implementation that |
| 96 | does not support a certain algorithm or key type can define such macros in a |
| 97 | simpler way that does not take unsupported argument values into account. |
| 98 | |
| 99 | Some macros define the minimum sufficient output buffer size for certain |
| 100 | functions. In some cases, an implementation is allowed to require a buffer size |
| 101 | that is larger than the theoretical minimum. An implementation must define |
| 102 | minimum-size macros in such a way that it guarantees that the buffer of the |
| 103 | resulting size is sufficient for the output of the corresponding function. Refer |
| 104 | to each macro’s documentation for the applicable requirements. |
| 105 | |
| 106 | Porting to a platform |
| 107 | ~~~~~~~~~~~~~~~~~~~~~ |
| 108 | |
| 109 | Platform assumptions |
| 110 | ^^^^^^^^^^^^^^^^^^^^ |
| 111 | |
| 112 | This specification is designed for a C99 platform. The interface is defined in |
| 113 | terms of C macros, functions and objects. |
| 114 | |
| 115 | The specification assumes 8-bit bytes, and “byte” and “octet” are used |
| 116 | synonymously. |
| 117 | |
| 118 | Platform-specific types |
| 119 | ^^^^^^^^^^^^^^^^^^^^^^^ |
| 120 | |
| 121 | The specification makes use of some types defined in C99. These types must be |
| 122 | defined in the implementation version of **psa/crypto.h** or by a header |
| 123 | included in this file. The following C99 types are used: |
| 124 | |
| 125 | ``uint8_t``, ``uint16_t``, ``uint32_t`` |
| 126 | Unsigned integer types with 8, 16 and 32 value bits respectively. |
| 127 | These types are defined by the C99 header **stdint.h**. |
| 128 | |
| 129 | Cryptographic hardware support |
| 130 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 131 | |
| 132 | Implementations are encouraged to make use of hardware accelerators where |
| 133 | available. A future version of this specification will define a function |
| 134 | interface that calls drivers for hardware accelerators and external |
| 135 | cryptographic hardware. |
| 136 | |
| 137 | Security requirements and recommendations |
| 138 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 139 | |
| 140 | Error detection |
| 141 | ^^^^^^^^^^^^^^^ |
| 142 | |
| 143 | Implementations that provide isolation between the caller and the cryptography |
| 144 | processing environment must validate parameters to ensure that the cryptography |
| 145 | processing environment is protected from attacks caused by passing invalid |
| 146 | parameters. |
| 147 | |
| 148 | Even implementations that do not provide isolation are recommended to detect bad |
| 149 | parameters and fail-safe where possible. |
| 150 | |
| 151 | Indirect object references |
| 152 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 153 | |
| 154 | Implementations can use different strategies for allocating key identifiers, |
| 155 | and other types of indirect object reference. |
| 156 | |
| 157 | Implementations that provide isolation between the caller and the cryptography |
| 158 | processing environment must consider the threats relating to abuse and misuse |
| 159 | of key identifiers and other indirect resource references. For example, |
| 160 | multi-part operations can be implemented as backend state to which the client |
| 161 | only maintains an indirect reference in the application's multi-part operation |
| 162 | object. |
| 163 | |
| 164 | An implementation that supports multiple callers must implement strict isolation |
| 165 | of API resources between different callers. For example, a client must not be |
| 166 | able to obtain a reference to another client's key by guessing the key |
| 167 | identifier value. Isolation of key identifiers can be achieved in several ways. |
| 168 | For example: |
| 169 | |
| 170 | - There is a single identifier namespace for all clients, and the |
| 171 | implementation verifies that the client is the owner of the identifier when |
| 172 | looking up the key. |
| 173 | - Each client has an independent identifier namespace, and the implementation |
| 174 | uses a client specific identifier-to-key mapping when looking up the key. |
| 175 | |
| 176 | After a volatile key identifier is destroyed, it is recommended that the |
| 177 | implementation does not immediately reuse the same identifier value for a |
| 178 | different key. This reduces the risk of an attack that is able to exploit a key |
| 179 | identifier reuse vulnerability within an application. |
| 180 | |
| 181 | .. _memory-cleanup: |
| 182 | |
| 183 | Memory cleanup |
| 184 | ^^^^^^^^^^^^^^ |
| 185 | |
| 186 | Implementations must wipe all sensitive data from memory when it is no longer |
| 187 | used. It is recommended that they wipe this sensitive data as soon as possible. All |
| 188 | temporary data used during the execution of a function, such as stack buffers, |
| 189 | must be wiped before the function returns. All data associated with an object, |
| 190 | such as a multi-part operation, must be wiped, at the latest, when the object |
| 191 | becomes inactive, for example, when a multi-part operation is aborted. |
| 192 | |
| 193 | The rationale for this non-functional requirement is to minimize impact if the |
| 194 | system is compromised. If sensitive data is wiped immediately after use, only |
| 195 | data that is currently in use can be leaked. It does not compromise past data. |
| 196 | |
| 197 | .. _key-material: |
| 198 | |
| 199 | Managing key material |
| 200 | ^^^^^^^^^^^^^^^^^^^^^ |
| 201 | |
| 202 | In implementations that have limited volatile memory for keys, the |
| 203 | implementation is permitted to store a `volatile key <volatile-keys>` to a |
| 204 | temporary location in non-volatile memory. The implementation must delete any |
| 205 | such copies when the key is destroyed, and it is recommended that these copies |
| 206 | are deleted as soon as the key is reloaded into volatile memory. An |
| 207 | implementation that uses this method must clear any stored volatile key material |
| 208 | on startup. |
| 209 | |
| 210 | Implementing the `memory cleanup rule <memory-cleanup>` for persistent keys |
| 211 | can result in inefficiencies when the same persistent key is used sequentially |
| 212 | in multiple cryptographic operations. The inefficiency stems from loading the |
| 213 | key from non-volatile storage on each use of the key. The `PSA_KEY_USAGE_CACHE` |
| 214 | policy allows an application to request that the implementation does not cleanup |
| 215 | non-essential copies of persistent key material, effectively suspending the |
| 216 | cleanup rules for that key. The effects of this policy depend on the |
| 217 | implementation and the key, for example: |
| 218 | |
| 219 | - For volatile keys or keys in a secure element with no open/close mechanism, |
| 220 | this is likely to have no effect. |
| 221 | - For persistent keys that are not in a secure element, this allows the |
| 222 | implementation to keep the key in a memory cache outside of the memory used |
| 223 | by ongoing operations. |
| 224 | - For keys in a secure element with an open/close mechanism, this is a hint to |
| 225 | keep the key open in the secure element. |
| 226 | |
| 227 | The application can indicate when it has finished using the key by calling |
| 228 | `psa_purge_key()`, to request that the key material is cleaned from memory. |
| 229 | |
| 230 | Safe outputs on error |
| 231 | ^^^^^^^^^^^^^^^^^^^^^ |
| 232 | |
| 233 | Implementations must ensure that confidential data is not written to output |
| 234 | parameters before validating that the disclosure of this confidential data is |
| 235 | authorized. This requirement is particularly important for implementations where |
| 236 | the caller can share memory with another security context, as described in the |
| 237 | `stability-of-parameters` section. |
| 238 | |
| 239 | In most cases, the specification does not define the content of output |
| 240 | parameters when an error occurs. It is recommended that implementations try to |
| 241 | ensure that the content of output parameters is as safe as possible, in case an |
| 242 | application flaw or a data leak causes it to be used. In particular, Arm |
| 243 | recommends that implementations avoid placing partial output in output buffers |
| 244 | when an action is interrupted. The meaning of “safe as possible” depends on the |
| 245 | implementation, as different environments require different compromises between |
| 246 | implementation complexity, overall robustness and performance. Some common |
| 247 | strategies are to leave output parameters unchanged, in case of errors, or |
| 248 | zeroing them out. |
| 249 | |
| 250 | Attack resistance |
| 251 | ^^^^^^^^^^^^^^^^^ |
| 252 | |
| 253 | Cryptographic code tends to manipulate high-value secrets, from which other |
| 254 | secrets can be unlocked. As such, it is a high-value target for attacks. There |
| 255 | is a vast body of literature on attack types, such as side channel attacks and |
| 256 | glitch attacks. Typical side channels include timing, cache access patterns, |
| 257 | branch-prediction access patterns, power consumption, radio emissions and more. |
| 258 | |
| 259 | This specification does not specify particular requirements for attack |
| 260 | resistance. Implementers are encouraged to consider the attack resistance |
| 261 | desired in each use case and design their implementation accordingly. Security |
| 262 | standards for attack resistance for particular targets might be applicable in |
| 263 | certain use cases. |
| 264 | |
| 265 | Other implementation considerations |
| 266 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 267 | |
| 268 | Philosophy of resource management |
| 269 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 270 | |
| 271 | The specification allows most functions to return |
| 272 | `PSA_ERROR_INSUFFICIENT_MEMORY`. This gives implementations the freedom to |
| 273 | manage memory as they please. |
| 274 | |
| 275 | Alternatively, the interface is also designed for conservative strategies of |
| 276 | memory management. An implementation can avoid dynamic memory allocation |
| 277 | altogether by obeying certain restrictions: |
| 278 | |
| 279 | - Pre-allocate memory for a predefined number of keys, each with sufficient |
| 280 | memory for all key types that can be stored. |
| 281 | - For multi-part operations, in an implementation without isolation, place all |
| 282 | the data that needs to be carried over from one step to the next in the |
| 283 | operation object. The application is then fully in control of how memory is |
| 284 | allocated for the operation. |
| 285 | - In an implementation with isolation, pre-allocate memory for a predefined |
| 286 | number of operations inside the cryptoprocessor. |
| 287 | |
| 288 | .. Inclusion of algorithms |
| 289 | |
| 290 | Inline algorithm-generic functions into specialized functions at compile/link time |