/src/mbedtls/library/psa_crypto_storage.h
Line | Count | Source |
1 | | /** |
2 | | * \file psa_crypto_storage.h |
3 | | * |
4 | | * \brief PSA cryptography module: Mbed TLS key storage |
5 | | */ |
6 | | /* |
7 | | * Copyright The Mbed TLS Contributors |
8 | | * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
9 | | */ |
10 | | |
11 | | #ifndef PSA_CRYPTO_STORAGE_H |
12 | | #define PSA_CRYPTO_STORAGE_H |
13 | | |
14 | | #ifdef __cplusplus |
15 | | extern "C" { |
16 | | #endif |
17 | | |
18 | | #include "psa/crypto.h" |
19 | | #include "psa/crypto_se_driver.h" |
20 | | |
21 | | #include <stdint.h> |
22 | | #include <string.h> |
23 | | |
24 | | /* Limit the maximum key size in storage. */ |
25 | | #if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS) |
26 | | /* Reflect the maximum size for the key buffer. */ |
27 | | #define PSA_CRYPTO_MAX_STORAGE_SIZE (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE) |
28 | | #else |
29 | | /* Just set an upper boundary but it should have no effect since the key size |
30 | | * is limited in memory. */ |
31 | 0 | #define PSA_CRYPTO_MAX_STORAGE_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS)) |
32 | | #endif |
33 | | |
34 | | /* Sanity check: a file size must fit in 32 bits. Allow a generous |
35 | | * 64kB of metadata. */ |
36 | | #if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000 |
37 | | #error "PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000" |
38 | | #endif |
39 | | |
40 | | /** The maximum permitted persistent slot number. |
41 | | * |
42 | | * In Mbed Crypto 0.1.0b: |
43 | | * - Using the file backend, all key ids are ok except 0. |
44 | | * - Using the ITS backend, all key ids are ok except 0xFFFFFF52 |
45 | | * (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the |
46 | | * device's random seed (if this feature is enabled). |
47 | | * - Only key ids from 1 to #MBEDTLS_PSA_KEY_SLOT_COUNT are actually used. |
48 | | * |
49 | | * Since we need to preserve the random seed, avoid using that key slot. |
50 | | * Reserve a whole range of key slots just in case something else comes up. |
51 | | * |
52 | | * This limitation will probably become moot when we implement client |
53 | | * separation for key storage. |
54 | | */ |
55 | 0 | #define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX |
56 | | |
57 | | /** |
58 | | * \brief Checks if persistent data is stored for the given key slot number |
59 | | * |
60 | | * This function checks if any key data or metadata exists for the key slot in |
61 | | * the persistent storage. |
62 | | * |
63 | | * \param key Persistent identifier to check. |
64 | | * |
65 | | * \retval 0 |
66 | | * No persistent data present for slot number |
67 | | * \retval 1 |
68 | | * Persistent data present for slot number |
69 | | */ |
70 | | int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key); |
71 | | |
72 | | /** |
73 | | * \brief Format key data and metadata and save to a location for given key |
74 | | * slot. |
75 | | * |
76 | | * This function formats the key data and metadata and saves it to a |
77 | | * persistent storage backend. The storage location corresponding to the |
78 | | * key slot must be empty, otherwise this function will fail. This function |
79 | | * should be called after loading the key into an internal slot to ensure the |
80 | | * persistent key is not saved into a storage location corresponding to an |
81 | | * already occupied non-persistent key, as well as ensuring the key data is |
82 | | * validated. |
83 | | * |
84 | | * Note: This function will only succeed for key buffers which are not |
85 | | * empty. If passed a NULL pointer or zero-length, the function will fail |
86 | | * with #PSA_ERROR_INVALID_ARGUMENT. |
87 | | * |
88 | | * \param[in] attr The attributes of the key to save. |
89 | | * The key identifier field in the attributes |
90 | | * determines the key's location. |
91 | | * \param[in] data Buffer containing the key data. |
92 | | * \param data_length The number of bytes that make up the key data. |
93 | | * |
94 | | * \retval #PSA_SUCCESS \emptydescription |
95 | | * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription |
96 | | * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription |
97 | | * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription |
98 | | * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription |
99 | | * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription |
100 | | * \retval #PSA_ERROR_DATA_INVALID \emptydescription |
101 | | * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription |
102 | | */ |
103 | | psa_status_t psa_save_persistent_key(const psa_key_attributes_t *attr, |
104 | | const uint8_t *data, |
105 | | const size_t data_length); |
106 | | |
107 | | /** |
108 | | * \brief Parses key data and metadata and load persistent key for given |
109 | | * key slot number. |
110 | | * |
111 | | * This function reads from a storage backend, parses the key data and |
112 | | * metadata and writes them to the appropriate output parameters. |
113 | | * |
114 | | * Note: This function allocates a buffer and returns a pointer to it through |
115 | | * the data parameter. On successful return, the pointer is guaranteed to be |
116 | | * valid and the buffer contains at least one byte of data. |
117 | | * psa_free_persistent_key_data() must be called on the data buffer |
118 | | * afterwards to zeroize and free this buffer. |
119 | | * |
120 | | * \param[in,out] attr On input, the key identifier field identifies |
121 | | * the key to load. Other fields are ignored. |
122 | | * On success, the attribute structure contains |
123 | | * the key metadata that was loaded from storage. |
124 | | * \param[out] data Pointer to an allocated key data buffer on return. |
125 | | * \param[out] data_length The number of bytes that make up the key data. |
126 | | * |
127 | | * \retval #PSA_SUCCESS \emptydescription |
128 | | * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription |
129 | | * \retval #PSA_ERROR_DATA_INVALID \emptydescription |
130 | | * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription |
131 | | * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription |
132 | | */ |
133 | | psa_status_t psa_load_persistent_key(psa_key_attributes_t *attr, |
134 | | uint8_t **data, |
135 | | size_t *data_length); |
136 | | |
137 | | /** |
138 | | * \brief Remove persistent data for the given key slot number. |
139 | | * |
140 | | * \param key Persistent identifier of the key to remove |
141 | | * from persistent storage. |
142 | | * |
143 | | * \retval #PSA_SUCCESS |
144 | | * The key was successfully removed, |
145 | | * or the key did not exist. |
146 | | * \retval #PSA_ERROR_DATA_INVALID \emptydescription |
147 | | */ |
148 | | psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key); |
149 | | |
150 | | /** |
151 | | * \brief Free the temporary buffer allocated by psa_load_persistent_key(). |
152 | | * |
153 | | * This function must be called at some point after psa_load_persistent_key() |
154 | | * to zeroize and free the memory allocated to the buffer in that function. |
155 | | * |
156 | | * \param key_data Buffer for the key data. |
157 | | * \param key_data_length Size of the key data buffer. |
158 | | * |
159 | | */ |
160 | | void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length); |
161 | | |
162 | | /** |
163 | | * \brief Formats key data and metadata for persistent storage |
164 | | * |
165 | | * \param[in] data Buffer containing the key data. |
166 | | * \param data_length Length of the key data buffer. |
167 | | * \param[in] attr The core attributes of the key. |
168 | | * \param[out] storage_data Output buffer for the formatted data. |
169 | | * |
170 | | */ |
171 | | void psa_format_key_data_for_storage(const uint8_t *data, |
172 | | const size_t data_length, |
173 | | const psa_key_attributes_t *attr, |
174 | | uint8_t *storage_data); |
175 | | |
176 | | /** |
177 | | * \brief Parses persistent storage data into key data and metadata |
178 | | * |
179 | | * \param[in] storage_data Buffer for the storage data. |
180 | | * \param storage_data_length Length of the storage data buffer |
181 | | * \param[out] key_data On output, pointer to a newly allocated buffer |
182 | | * containing the key data. This must be freed |
183 | | * using psa_free_persistent_key_data() |
184 | | * \param[out] key_data_length Length of the key data buffer |
185 | | * \param[out] attr On success, the attribute structure is filled |
186 | | * with the loaded key metadata. |
187 | | * |
188 | | * \retval #PSA_SUCCESS \emptydescription |
189 | | * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription |
190 | | * \retval #PSA_ERROR_DATA_INVALID \emptydescription |
191 | | */ |
192 | | psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, |
193 | | size_t storage_data_length, |
194 | | uint8_t **key_data, |
195 | | size_t *key_data_length, |
196 | | psa_key_attributes_t *attr); |
197 | | |
198 | | #if defined(MBEDTLS_PSA_CRYPTO_SE_C) |
199 | | /** This symbol is defined if transaction support is required. */ |
200 | | #define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS 1 |
201 | | #endif |
202 | | |
203 | | #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) |
204 | | |
205 | | /** The type of transaction that is in progress. |
206 | | */ |
207 | | /* This is an integer type rather than an enum for two reasons: to support |
208 | | * unknown values when loading a transaction file, and to ensure that the |
209 | | * type has a known size. |
210 | | */ |
211 | | typedef uint16_t psa_crypto_transaction_type_t; |
212 | | |
213 | | /** No transaction is in progress. |
214 | | * |
215 | | * This has the value 0, so zero-initialization sets a transaction's type to |
216 | | * this value. |
217 | | */ |
218 | | #define PSA_CRYPTO_TRANSACTION_NONE ((psa_crypto_transaction_type_t) 0x0000) |
219 | | |
220 | | /** A key creation transaction. |
221 | | * |
222 | | * This is only used for keys in an external cryptoprocessor (secure element). |
223 | | * Keys in RAM or in internal storage are created atomically in storage |
224 | | * (simple file creation), so they do not need a transaction mechanism. |
225 | | */ |
226 | 0 | #define PSA_CRYPTO_TRANSACTION_CREATE_KEY ((psa_crypto_transaction_type_t) 0x0001) |
227 | | |
228 | | /** A key destruction transaction. |
229 | | * |
230 | | * This is only used for keys in an external cryptoprocessor (secure element). |
231 | | * Keys in RAM or in internal storage are destroyed atomically in storage |
232 | | * (simple file deletion), so they do not need a transaction mechanism. |
233 | | */ |
234 | 0 | #define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ((psa_crypto_transaction_type_t) 0x0002) |
235 | | |
236 | | /** Transaction data. |
237 | | * |
238 | | * This type is designed to be serialized by writing the memory representation |
239 | | * and reading it back on the same device. |
240 | | * |
241 | | * \note The transaction mechanism is not thread-safe. There can only be one |
242 | | * single active transaction at a time. |
243 | | * The transaction object is #psa_crypto_transaction. |
244 | | * |
245 | | * \note If an API call starts a transaction, it must complete this transaction |
246 | | * before returning to the application. |
247 | | * |
248 | | * The lifetime of a transaction is the following (note that only one |
249 | | * transaction may be active at a time): |
250 | | * |
251 | | * -# Call psa_crypto_prepare_transaction() to initialize the transaction |
252 | | * object in memory and declare the type of transaction that is starting. |
253 | | * -# Fill in the type-specific fields of #psa_crypto_transaction. |
254 | | * -# Call psa_crypto_save_transaction() to start the transaction. This |
255 | | * saves the transaction data to internal storage. |
256 | | * -# Perform the work of the transaction by modifying files, contacting |
257 | | * external entities, or whatever needs doing. Note that the transaction |
258 | | * may be interrupted by a power failure, so you need to have a way |
259 | | * recover from interruptions either by undoing what has been done |
260 | | * so far or by resuming where you left off. |
261 | | * -# If there are intermediate stages in the transaction, update |
262 | | * the fields of #psa_crypto_transaction and call |
263 | | * psa_crypto_save_transaction() again when each stage is reached. |
264 | | * -# When the transaction is over, call psa_crypto_stop_transaction() to |
265 | | * remove the transaction data in storage and in memory. |
266 | | * |
267 | | * If the system crashes while a transaction is in progress, psa_crypto_init() |
268 | | * calls psa_crypto_load_transaction() and takes care of completing or |
269 | | * rewinding the transaction. This is done in psa_crypto_recover_transaction() |
270 | | * in psa_crypto.c. If you add a new type of transaction, be |
271 | | * sure to add code for it in psa_crypto_recover_transaction(). |
272 | | */ |
273 | | typedef union { |
274 | | /* Each element of this union must have the following properties |
275 | | * to facilitate serialization and deserialization: |
276 | | * |
277 | | * - The element is a struct. |
278 | | * - The first field of the struct is `psa_crypto_transaction_type_t type`. |
279 | | * - Elements of the struct are arranged such a way that there is |
280 | | * no padding. |
281 | | */ |
282 | | struct psa_crypto_transaction_unknown_s { |
283 | | psa_crypto_transaction_type_t type; |
284 | | uint16_t unused1; |
285 | | uint32_t unused2; |
286 | | uint64_t unused3; |
287 | | uint64_t unused4; |
288 | | } unknown; |
289 | | /* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or |
290 | | * #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */ |
291 | | struct psa_crypto_transaction_key_s { |
292 | | psa_crypto_transaction_type_t type; |
293 | | uint16_t unused1; |
294 | | psa_key_lifetime_t lifetime; |
295 | | psa_key_slot_number_t slot; |
296 | | mbedtls_svc_key_id_t id; |
297 | | } key; |
298 | | } psa_crypto_transaction_t; |
299 | | |
300 | | /** The single active transaction. |
301 | | */ |
302 | | extern psa_crypto_transaction_t psa_crypto_transaction; |
303 | | |
304 | | /** Prepare for a transaction. |
305 | | * |
306 | | * There must not be an ongoing transaction. |
307 | | * |
308 | | * \param type The type of transaction to start. |
309 | | */ |
310 | | static inline void psa_crypto_prepare_transaction( |
311 | | psa_crypto_transaction_type_t type) |
312 | 0 | { |
313 | 0 | psa_crypto_transaction.unknown.type = type; |
314 | 0 | } Unexecuted instantiation: psa_crypto_helpers.c:psa_crypto_prepare_transaction Unexecuted instantiation: psa_crypto.c:psa_crypto_prepare_transaction Unexecuted instantiation: psa_crypto_slot_management.c:psa_crypto_prepare_transaction Unexecuted instantiation: psa_crypto_storage.c:psa_crypto_prepare_transaction |
315 | | |
316 | | /** Save the transaction data to storage. |
317 | | * |
318 | | * You may call this function multiple times during a transaction to |
319 | | * atomically update the transaction state. |
320 | | * |
321 | | * \retval #PSA_SUCCESS \emptydescription |
322 | | * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription |
323 | | * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription |
324 | | * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription |
325 | | */ |
326 | | psa_status_t psa_crypto_save_transaction(void); |
327 | | |
328 | | /** Load the transaction data from storage, if any. |
329 | | * |
330 | | * This function is meant to be called from psa_crypto_init() to recover |
331 | | * in case a transaction was interrupted by a system crash. |
332 | | * |
333 | | * \retval #PSA_SUCCESS |
334 | | * The data about the ongoing transaction has been loaded to |
335 | | * #psa_crypto_transaction. |
336 | | * \retval #PSA_ERROR_DOES_NOT_EXIST |
337 | | * There is no ongoing transaction. |
338 | | * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription |
339 | | * \retval #PSA_ERROR_DATA_INVALID \emptydescription |
340 | | * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription |
341 | | */ |
342 | | psa_status_t psa_crypto_load_transaction(void); |
343 | | |
344 | | /** Indicate that the current transaction is finished. |
345 | | * |
346 | | * Call this function at the very end of transaction processing. |
347 | | * This function does not "commit" or "abort" the transaction: the storage |
348 | | * subsystem has no concept of "commit" and "abort", just saving and |
349 | | * removing the transaction information in storage. |
350 | | * |
351 | | * This function erases the transaction data in storage (if any) and |
352 | | * resets the transaction data in memory. |
353 | | * |
354 | | * \retval #PSA_SUCCESS |
355 | | * There was transaction data in storage. |
356 | | * \retval #PSA_ERROR_DOES_NOT_EXIST |
357 | | * There was no transaction data in storage. |
358 | | * \retval #PSA_ERROR_STORAGE_FAILURE |
359 | | * It was impossible to determine whether there was transaction data |
360 | | * in storage, or the transaction data could not be erased. |
361 | | */ |
362 | | psa_status_t psa_crypto_stop_transaction(void); |
363 | | |
364 | | /** The ITS file identifier for the transaction data. |
365 | | * |
366 | | * 0xffffffNN = special file; 0x74 = 't' for transaction. |
367 | | */ |
368 | 0 | #define PSA_CRYPTO_ITS_TRANSACTION_UID ((psa_key_id_t) 0xffffff74) |
369 | | |
370 | | #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */ |
371 | | |
372 | | #if defined(MBEDTLS_PSA_INJECT_ENTROPY) |
373 | | /** Backend side of mbedtls_psa_inject_entropy(). |
374 | | * |
375 | | * This function stores the supplied data into the entropy seed file. |
376 | | * |
377 | | * \retval #PSA_SUCCESS |
378 | | * Success |
379 | | * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription |
380 | | * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription |
381 | | * \retval #PSA_ERROR_NOT_PERMITTED |
382 | | * The entropy seed file already exists. |
383 | | */ |
384 | | psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed, |
385 | | size_t seed_size); |
386 | | #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ |
387 | | |
388 | | #ifdef __cplusplus |
389 | | } |
390 | | #endif |
391 | | |
392 | | #endif /* PSA_CRYPTO_STORAGE_H */ |