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

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.