blob: 8baf9913ab15dd457b0854bd533a1b8dafdc053e [file] [log] [blame]
Gilles Peskine6c723a22020-04-17 16:57:52 +02001Library conventions
2-------------------
3
4Error handling
5~~~~~~~~~~~~~~
6
7Return status
8^^^^^^^^^^^^^
9
10Almost all functions return a status indication of type `psa_status_t`. This
11is an enumeration of integer values, with ``0`` (`PSA_SUCCESS`) indicating
12successful operation and other values indicating errors. The exceptions are
13functions which only access objects that are intended to be implemented as
14simple data structures. Such functions cannot fail and either return
15``void`` or a data value.
16
17Unless specified otherwise, if multiple error conditions apply, an
18implementation is free to return any of the applicable error codes. The choice
19of error code is considered an implementation quality issue. Different
20implementations can make different choices, for example to favor code size over
21ease of debugging or vice versa.
22
23If the behavior is undefined, for example, if a function receives an invalid
24pointer as a parameter, this specification makes no guarantee that the function
25will return an error. Implementations are encouraged to return an error or halt
26the application in a manner that is appropriate for the platform if the
27undefined behavior condition can be detected. However, application developers need to be aware that undefined behavior conditions cannot be detected in general.
28
29Behavior on error
30^^^^^^^^^^^^^^^^^
31
32All function calls must be implemented atomically:
33
34- When a function returns a type other than `psa_status_t`, the requested
35 action has been carried out.
36- When a function returns the status `PSA_SUCCESS`, the requested action has
37 been carried out.
38- When a function returns another status of type `psa_status_t`, no action
39 has been carried out. The content of the output parameters is undefined, but
40 otherwise the state of the system has not changed, except as described below.
41
42In general, functions that modify the system state, for example, creating or
43destroying a key, must leave the system state unchanged if they return an error
44code. There are specific conditions that can result in different behavior:
45
46- The status `PSA_ERROR_BAD_STATE` indicates that a parameter was not in a
47 valid state for the requested action. This parameter might have been modified
48 by the call and is now in an undefined state. The only valid action on an
49 object in an undefined state is to abort it with the appropriate
50 ``psa_abort_xxx()`` function.
51- The status `PSA_ERROR_INSUFFICIENT_DATA` indicates that a key
52 derivation object has reached its maximum capacity. The key derivation
53 operation might have been modified by the call. Any further attempt to obtain
54 output from the key derivation operation will return
55 `PSA_ERROR_INSUFFICIENT_DATA`.
56- The status `PSA_ERROR_COMMUNICATION_FAILURE` indicates that the
57 communication between the application and the cryptoprocessor has broken
58 down. In this case, the cryptoprocessor must either finish the requested
59 action successfully, or interrupt the action and roll back the system to its
60 original state. Because it is often impossible to report the outcome to the
61 application after a communication failure, this specification does not
62 provide a way for the application to determine whether the action was
63 successful.
64- The statuses `PSA_ERROR_STORAGE_FAILURE`, `PSA_ERROR_DATA_CORRUPT`, `PSA_ERROR_HARDWARE_FAILURE`
65 and `PSA_ERROR_CORRUPTION_DETECTED` might indicate data corruption in the
66 system state. When a function returns one of these statuses, the system state
67 might have changed from its previous state before the function call, even
68 though the function call failed.
69- Some system states cannot be rolled back, for example, the internal state of
70 the random number generator or the content of access logs.
71
72Unless otherwise documented, the content of output parameters is not defined
73when a function returns a status other than `PSA_SUCCESS`. It is recommended
74that implementations set output parameters to safe defaults to avoid leaking
75confidential data and limit risk, in case an application does not properly
76handle all errors.
77
78Parameter conventions
79~~~~~~~~~~~~~~~~~~~~~
80
81Pointer conventions
82^^^^^^^^^^^^^^^^^^^
83
84Unless explicitly stated in the documentation of a function, all pointers must
85be valid pointers to an object of the specified type.
86
87A parameter is considered a **buffer** if it points to an array of bytes. A
88buffer parameter always has the type ``uint8_t *`` or ``const uint8_t *``, and
89always has an associated parameter indicating the size of the array. Note that a
90parameter of type ``void *`` is never considered a buffer.
91
92All parameters of pointer type must be valid non-null pointers, unless the
93pointer is to a buffer of length ``0`` or the function’s documentation
94explicitly describes the behavior when the pointer is null. Passing a null
95pointer as a function parameter in other cases is expected to abort the caller
96on implementations where this is the normal behavior for a null pointer
97dereference.
98
99Pointers to input parameters can be in read-only memory. Output parameters must
100be in writable memory. Output parameters that are not buffers must also be
101readable, and the implementation must be able to write to a non-buffer output
102parameter and read back the same value, as explained in the
103:title:`stability-of-parameters` section.
104
105Input buffer sizes
106^^^^^^^^^^^^^^^^^^
107
108For input buffers, the parameter convention is:
109
110``const uint8_t *foo``
111 Pointer to the first byte of the data. The pointer
112 can be invalid if the buffer size is ``0``.
113
114``size_t foo_length``
115 Size of the buffer in bytes.
116
117The interface never uses input-output buffers.
118
119Output buffer sizes
120^^^^^^^^^^^^^^^^^^^
121
122For output buffers, the parameter convention is:
123
124``uint8_t *foo``
125 Pointer to the first byte of the data. The pointer can be
126 invalid if the buffer size is ``0``.
127
128``size_t foo_size``
129 The size of the buffer in bytes.
130
131``size_t *foo_length``
132 On successful return, contains the length of the
133 output in bytes.
134
135The content of the data buffer and of ``*foo_length`` on errors is unspecified,
136unless explicitly mentioned in the function description. They might be unmodified
137or set to a safe default. On successful completion, the content of the buffer
138between the offsets ``*foo_length`` and ``foo_size`` is also unspecified.
139
140Functions return `PSA_ERROR_BUFFER_TOO_SMALL` if the buffer size is
141insufficient to carry out the requested operation. The interface defines macros
142to calculate a sufficient buffer size for each operation that has an output
143buffer. These macros return compile-time constants if their arguments are
144compile-time constants, so they are suitable for static or stack allocation.
145Refer to an individual function’s documentation for the associated output size
146macro.
147
148Some functions always return exactly as much data as the size of the output
149buffer. In this case, the parameter convention changes to:
150
151``uint8_t *foo``
152 Pointer to the first byte of the output. The pointer can be
153 invalid if the buffer size is ``0``.
154
155``size_t foo_length``
156 The number of bytes to return in ``foo`` if
157 successful.
158
159Overlap between parameters
160^^^^^^^^^^^^^^^^^^^^^^^^^^
161
162Output parameters that are not buffers must not overlap with any input buffer or
163with any other output parameter. Otherwise, the behavior is undefined.
164
165Output buffers can overlap with input buffers. In this event, the implementation
166must return the same result as if the buffers did not overlap. The
167implementation must behave as if it had copied all the inputs into temporary
168memory, as far as the result is concerned. However, it is possible that overlap
169between parameters will affect the performance of a function call. Overlap might
170also affect memory management security if the buffer is located in memory that
171the caller shares with another security context, as described in the
172:title:`stability-of-parameters` section.
173
174.. _stability-of-parameters:
175
176Stability of parameters
177^^^^^^^^^^^^^^^^^^^^^^^
178
179In some environments, it is possible for the content of a parameter to change
180while a function is executing. It might also be possible for the content of an
181output parameter to be read before the function terminates. This can happen if
182the application is multithreaded. In some implementations, memory can be shared
183between security contexts, for example, between tasks in a multitasking
184operating system, between a user land task and the kernel, or between the
185Non-secure world and the Secure world of a trusted execution environment.
186
187This section describes the assumptions that an implementation can make about
188function parameters, and the guarantees that the implementation must provide
189about how it accesses parameters.
190
191Parameters that are not buffers are assumed to be under the caller’s full
192control. In a shared memory environment, this means that the parameter must be
193in memory that is exclusively accessible by the application. In a multithreaded
194environment, this means that the parameter must not be modified during the
195execution, and the value of an output parameter is undetermined until the
196function returns. The implementation can read an input parameter that is not a
197buffer multiple times and expect to read the same data. The implementation can
198write to an output parameter that is not a buffer and expect to read back the
199value that it last wrote. The implementation has the same permissions on buffers
200that overlap with a buffer in the opposite direction.
201
202In an environment with multiple threads or with shared memory, the
203implementation carefully accesses non-overlapping buffer parameters in order to
204prevent any security risk resulting from the content of the buffer being
205modified or observed during the execution of the function. In an input buffer
206that does not overlap with an output buffer, the implementation reads each byte
207of the input once, at most. The implementation does not read from an output
208buffer that does not overlap with an input buffer. Additionally, the
209implementation does not write data to a non-overlapping output buffer if this
210data is potentially confidential and the implementation has not yet verified
211that outputting this data is authorized.
212
213Unless otherwise specified, the implementation must not keep a reference to any
214parameter once a function call has returned.
215
216Key types and algorithms
217~~~~~~~~~~~~~~~~~~~~~~~~
218
219Types of cryptographic keys and cryptographic algorithms are encoded separately.
220Each is encoded by using an integral type: `psa_key_type_t` and
221`psa_algorithm_t`, respectively.
222
223There is some overlap in the information conveyed by key types and algorithms.
224Both types contain enough information, so that the meaning of an algorithm type
225value does not depend on what type of key it is used with, and vice versa.
226However, the particular instance of an algorithm might depend on the key type. For
227example, the algorithm `PSA_ALG_GCM` can be instantiated as any AEAD algorithm
228using the GCM mode over a block cipher. The underlying block cipher is
229determined by the key type.
230
231Key types do not encode the key size. For example, AES-128, AES-192 and AES-256
232share a key type `PSA_KEY_TYPE_AES`.
233
234Structure of key and algorithm types
235^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
236
237Both types use a partial bitmask structure, which allows the analysis and
238building of values from parts. However, the interface defines constants, so that
239applications do not need to depend on the encoding, and an implementation might
240only care about the encoding for code size optimization.
241
242The encodings follows a few conventions:
243
244- The highest bit is a vendor flag. Current and future versions of this
245 specification will only define values where this bit is clear.
246 Implementations that wish to define additional implementation-specific values
247 must use values where this bit is set, to avoid conflicts with future
248 versions of this specification.
249- The next few highest bits indicate the corresponding algorithm category:
250 hash, MAC, symmetric cipher, asymmetric encryption, and so on.
251- The following bits identify a family of algorithms in a category-dependent
252 manner.
253- In some categories and algorithm families, the lowest-order bits indicate a
254 variant in a systematic way. For example, algorithm families that are
255 parametrized around a hash function encode the hash in the 8 lowest bits.
256
257.. _concurrency:
258
259Concurrent calls
260~~~~~~~~~~~~~~~~
261
262In some environments, an application can make calls to the PSA crypto API in
263separate threads. In such an environment, concurrent calls are performed
264correctly, as if the calls were executed in sequence, provided that they obey
265the following constraints:
266
267- There is no overlap between an output parameter of one call and an input or
268 output parameter of another call. Overlap between input parameters is
269 permitted.
270- If a call destroys a key, then no other call must destroy or use that key.
271 *Using*, in this context, includes all functions of multi-part operations
272 which have used the key as an input in a previous function.
273- Concurrent calls that use the same key are permitted.
274- Concurrent calls must not use the same operation object.
275
276If any of these constraints are violated, the behavior is undefined.
277
278If the application modifies an input parameter while a function call is in
279progress, the behavior is undefined.
280
281Individual implementations can provide additional guarantees.