Branch data Line data Source code
1 : : /*
2 : : * PSA crypto layer on top of Mbed TLS crypto
3 : : */
4 : : /*
5 : : * Copyright The Mbed TLS Contributors
6 : : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 : : */
8 : :
9 : : #ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
10 : : #define PSA_CRYPTO_SLOT_MANAGEMENT_H
11 : :
12 : : #include "psa/crypto.h"
13 : : #include "psa_crypto_core.h"
14 : : #include "psa_crypto_se.h"
15 : :
16 : : /** Range of volatile key identifiers.
17 : : *
18 : : * The first #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
19 : : * range of key identifiers are reserved for volatile key identifiers.
20 : : *
21 : : * If \c id is a a volatile key identifier, #PSA_KEY_ID_VOLATILE_MIN - \c id
22 : : * indicates the key slot containing the volatile key definition. See
23 : : * psa_crypto_slot_management.c for details.
24 : : */
25 : :
26 : : /** The minimum value for a volatile key identifier.
27 : : */
28 : : #define PSA_KEY_ID_VOLATILE_MIN PSA_KEY_ID_VENDOR_MIN
29 : :
30 : : /** The maximum value for a volatile key identifier.
31 : : */
32 : : #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
33 : : #define PSA_KEY_ID_VOLATILE_MAX (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1)
34 : : #else /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
35 : : #define PSA_KEY_ID_VOLATILE_MAX \
36 : : (PSA_KEY_ID_VOLATILE_MIN + MBEDTLS_PSA_KEY_SLOT_COUNT - 1)
37 : : #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
38 : :
39 : : /** Test whether a key identifier is a volatile key identifier.
40 : : *
41 : : * \param key_id Key identifier to test.
42 : : *
43 : : * \retval 1
44 : : * The key identifier is a volatile key identifier.
45 : : * \retval 0
46 : : * The key identifier is not a volatile key identifier.
47 : : */
48 : 374 : static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
49 : : {
50 : 374 : return (key_id >= PSA_KEY_ID_VOLATILE_MIN) &&
51 : : (key_id <= PSA_KEY_ID_VOLATILE_MAX);
52 : : }
53 : :
54 : : /** Get the description of a key given its identifier and lock it.
55 : : *
56 : : * The descriptions of volatile keys and loaded persistent keys are stored in
57 : : * key slots. This function returns a pointer to the key slot containing the
58 : : * description of a key given its identifier.
59 : : *
60 : : * In case of a persistent key, the function loads the description of the key
61 : : * into a key slot if not already done.
62 : : *
63 : : * On success, the returned key slot has been registered for reading.
64 : : * It is the responsibility of the caller to call psa_unregister_read(slot)
65 : : * when they have finished reading the contents of the slot.
66 : : *
67 : : * On failure, `*p_slot` is set to NULL. This ensures that it is always valid
68 : : * to call psa_unregister_read on the returned slot.
69 : : *
70 : : * \param key Key identifier to query.
71 : : * \param[out] p_slot On success, `*p_slot` contains a pointer to the
72 : : * key slot containing the description of the key
73 : : * identified by \p key.
74 : : *
75 : : * \retval #PSA_SUCCESS
76 : : * \p *p_slot contains a pointer to the key slot containing the
77 : : * description of the key identified by \p key.
78 : : * The key slot counter has been incremented.
79 : : * \retval #PSA_ERROR_BAD_STATE
80 : : * The library has not been initialized.
81 : : * \retval #PSA_ERROR_INVALID_HANDLE
82 : : * \p key is not a valid key identifier.
83 : : * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
84 : : * \p key is a persistent key identifier. The implementation does not
85 : : * have sufficient resources to load the persistent key. This can be
86 : : * due to a lack of empty key slot, or available memory.
87 : : * \retval #PSA_ERROR_DOES_NOT_EXIST
88 : : * There is no key with key identifier \p key.
89 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription
90 : : * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
91 : : * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
92 : : */
93 : : psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key,
94 : : psa_key_slot_t **p_slot);
95 : :
96 : : /** Initialize the key slot structures.
97 : : *
98 : : * \retval #PSA_SUCCESS
99 : : * Currently this function always succeeds.
100 : : */
101 : : psa_status_t psa_initialize_key_slots(void);
102 : :
103 : : #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
104 : : /* Allow test code to customize the key slice length. We use this in tests
105 : : * that exhaust the key store to reach a full key store in reasonable time
106 : : * and memory.
107 : : *
108 : : * The length of each slice must be between 1 and
109 : : * (1 << KEY_ID_SLOT_INDEX_WIDTH) inclusive.
110 : : *
111 : : * The length for a given slice index must not change while
112 : : * the key store is initialized.
113 : : */
114 : : extern size_t (*mbedtls_test_hook_psa_volatile_key_slice_length)(
115 : : size_t slice_idx);
116 : :
117 : : /* The number of volatile key slices. */
118 : : size_t psa_key_slot_volatile_slice_count(void);
119 : : #endif
120 : :
121 : : /** Delete all data from key slots in memory.
122 : : * This function is not thread safe, it wipes every key slot regardless of
123 : : * state and reader count. It should only be called when no slot is in use.
124 : : *
125 : : * This does not affect persistent storage. */
126 : : void psa_wipe_all_key_slots(void);
127 : :
128 : : /** Find a free key slot and reserve it to be filled with a key.
129 : : *
130 : : * This function finds a key slot that is free,
131 : : * sets its state to PSA_SLOT_FILLING and then returns the slot.
132 : : *
133 : : * On success, the key slot's state is PSA_SLOT_FILLING.
134 : : * It is the responsibility of the caller to change the slot's state to
135 : : * PSA_SLOT_EMPTY/FULL once key creation has finished.
136 : : *
137 : : * If multi-threading is enabled, the caller must hold the
138 : : * global key slot mutex.
139 : : *
140 : : * \param[out] volatile_key_id - If null, reserve a cache slot for
141 : : * a persistent or built-in key.
142 : : * - If non-null, allocate a slot for
143 : : * a volatile key. On success,
144 : : * \p *volatile_key_id is the
145 : : * identifier corresponding to the
146 : : * returned slot. It is the caller's
147 : : * responsibility to set this key identifier
148 : : * in the attributes.
149 : : * \param[out] p_slot On success, a pointer to the slot.
150 : : *
151 : : * \retval #PSA_SUCCESS \emptydescription
152 : : * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
153 : : * There were no free key slots.
154 : : * When #MBEDTLS_PSA_KEY_STORE_DYNAMIC is enabled, there was not
155 : : * enough memory to allocate more slots.
156 : : * \retval #PSA_ERROR_BAD_STATE \emptydescription
157 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED
158 : : * This function attempted to operate on a key slot which was in an
159 : : * unexpected state.
160 : : */
161 : : psa_status_t psa_reserve_free_key_slot(psa_key_id_t *volatile_key_id,
162 : : psa_key_slot_t **p_slot);
163 : :
164 : : #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
165 : : /** Return a key slot to the free list.
166 : : *
167 : : * Call this function when a slot obtained from psa_reserve_free_key_slot()
168 : : * is no longer in use.
169 : : *
170 : : * If multi-threading is enabled, the caller must hold the
171 : : * global key slot mutex.
172 : : *
173 : : * \param slice_idx The slice containing the slot.
174 : : * This is `slot->slice_index` when the slot
175 : : * is obtained from psa_reserve_free_key_slot().
176 : : * \param slot The key slot.
177 : : *
178 : : * \retval #PSA_SUCCESS \emptydescription
179 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED
180 : : * This function attempted to operate on a key slot which was in an
181 : : * unexpected state.
182 : : */
183 : : psa_status_t psa_free_key_slot(size_t slice_idx,
184 : : psa_key_slot_t *slot);
185 : : #endif /* MBEDTLS_PSA_KEY_STORE_DYNAMIC */
186 : :
187 : : /** Change the state of a key slot.
188 : : *
189 : : * This function changes the state of the key slot from expected_state to
190 : : * new state. If the state of the slot was not expected_state, the state is
191 : : * unchanged.
192 : : *
193 : : * If multi-threading is enabled, the caller must hold the
194 : : * global key slot mutex.
195 : : *
196 : : * \param[in] slot The key slot.
197 : : * \param[in] expected_state The current state of the slot.
198 : : * \param[in] new_state The new state of the slot.
199 : : *
200 : : * \retval #PSA_SUCCESS
201 : : The key slot's state variable is new_state.
202 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED
203 : : * The slot's state was not expected_state.
204 : : */
205 : 516 : static inline psa_status_t psa_key_slot_state_transition(
206 : : psa_key_slot_t *slot, psa_key_slot_state_t expected_state,
207 : : psa_key_slot_state_t new_state)
208 : : {
209 [ + - ]: 516 : if (slot->state != expected_state) {
210 : : return PSA_ERROR_CORRUPTION_DETECTED;
211 : : }
212 : 516 : slot->state = new_state;
213 : 516 : return PSA_SUCCESS;
214 : : }
215 : :
216 : : /** Register as a reader of a key slot.
217 : : *
218 : : * This function increments the key slot registered reader counter by one.
219 : : * If multi-threading is enabled, the caller must hold the
220 : : * global key slot mutex.
221 : : *
222 : : * \param[in] slot The key slot.
223 : : *
224 : : * \retval #PSA_SUCCESS
225 : : The key slot registered reader counter was incremented.
226 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED
227 : : * The reader counter already reached its maximum value and was not
228 : : * increased, or the slot's state was not PSA_SLOT_FULL.
229 : : */
230 : 374 : static inline psa_status_t psa_register_read(psa_key_slot_t *slot)
231 : : {
232 [ + - ]: 374 : if ((slot->state != PSA_SLOT_FULL) ||
233 [ + - ]: 374 : (slot->var.occupied.registered_readers >= SIZE_MAX)) {
234 : : return PSA_ERROR_CORRUPTION_DETECTED;
235 : : }
236 : 374 : slot->var.occupied.registered_readers++;
237 : :
238 : 374 : return PSA_SUCCESS;
239 : : }
240 : :
241 : : /** Unregister from reading a key slot.
242 : : *
243 : : * This function decrements the key slot registered reader counter by one.
244 : : * If the state of the slot is PSA_SLOT_PENDING_DELETION,
245 : : * and there is only one registered reader (the caller),
246 : : * this function will call psa_wipe_key_slot().
247 : : * If multi-threading is enabled, the caller must hold the
248 : : * global key slot mutex.
249 : : *
250 : : * \note To ease the handling of errors in retrieving a key slot
251 : : * a NULL input pointer is valid, and the function returns
252 : : * successfully without doing anything in that case.
253 : : *
254 : : * \param[in] slot The key slot.
255 : : * \retval #PSA_SUCCESS
256 : : * \p slot is NULL or the key slot reader counter has been
257 : : * decremented (and potentially wiped) successfully.
258 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED
259 : : * The slot's state was neither PSA_SLOT_FULL nor
260 : : * PSA_SLOT_PENDING_DELETION.
261 : : * Or a wipe was attempted and the slot's state was not
262 : : * PSA_SLOT_PENDING_DELETION.
263 : : * Or registered_readers was equal to 0.
264 : : */
265 : : psa_status_t psa_unregister_read(psa_key_slot_t *slot);
266 : :
267 : : /** Wrap a call to psa_unregister_read in the global key slot mutex.
268 : : *
269 : : * If threading is disabled, this simply calls psa_unregister_read.
270 : : *
271 : : * \note To ease the handling of errors in retrieving a key slot
272 : : * a NULL input pointer is valid, and the function returns
273 : : * successfully without doing anything in that case.
274 : : *
275 : : * \param[in] slot The key slot.
276 : : * \retval #PSA_SUCCESS
277 : : * \p slot is NULL or the key slot reader counter has been
278 : : * decremented (and potentially wiped) successfully.
279 : : * \retval #PSA_ERROR_CORRUPTION_DETECTED
280 : : * The slot's state was neither PSA_SLOT_FULL nor
281 : : * PSA_SLOT_PENDING_DELETION.
282 : : * Or a wipe was attempted and the slot's state was not
283 : : * PSA_SLOT_PENDING_DELETION.
284 : : * Or registered_readers was equal to 0.
285 : : */
286 : : psa_status_t psa_unregister_read_under_mutex(psa_key_slot_t *slot);
287 : :
288 : : /** Test whether a lifetime designates a key in an external cryptoprocessor.
289 : : *
290 : : * \param lifetime The lifetime to test.
291 : : *
292 : : * \retval 1
293 : : * The lifetime designates an external key. There should be a
294 : : * registered driver for this lifetime, otherwise the key cannot
295 : : * be created or manipulated.
296 : : * \retval 0
297 : : * The lifetime designates a key that is volatile or in internal
298 : : * storage.
299 : : */
300 : 176 : static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime)
301 : : {
302 : 176 : return PSA_KEY_LIFETIME_GET_LOCATION(lifetime)
303 : 176 : != PSA_KEY_LOCATION_LOCAL_STORAGE;
304 : : }
305 : :
306 : : /** Validate a key's location.
307 : : *
308 : : * This function checks whether the key's attributes point to a location that
309 : : * is known to the PSA Core, and returns the driver function table if the key
310 : : * is to be found in an external location.
311 : : *
312 : : * \param[in] lifetime The key lifetime attribute.
313 : : * \param[out] p_drv On success, when a key is located in external
314 : : * storage, returns a pointer to the driver table
315 : : * associated with the key's storage location.
316 : : *
317 : : * \retval #PSA_SUCCESS \emptydescription
318 : : * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
319 : : */
320 : : psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime,
321 : : psa_se_drv_table_entry_t **p_drv);
322 : :
323 : : /** Validate the persistence of a key.
324 : : *
325 : : * \param[in] lifetime The key lifetime attribute.
326 : : *
327 : : * \retval #PSA_SUCCESS \emptydescription
328 : : * \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys
329 : : * are not supported.
330 : : */
331 : : psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime);
332 : :
333 : : /** Validate a key identifier.
334 : : *
335 : : * \param[in] key The key identifier.
336 : : * \param[in] vendor_ok Non-zero to indicate that key identifiers in the
337 : : * vendor range are allowed, volatile key identifiers
338 : : * excepted \c 0 otherwise.
339 : : *
340 : : * \retval <> 0 if the key identifier is valid, 0 otherwise.
341 : : */
342 : : int psa_is_valid_key_id(mbedtls_svc_key_id_t key, int vendor_ok);
343 : :
344 : : #endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
|