blob: 16f5d5cac4930d7dc4b7f924ce66c02c26d4824a [file] [log] [blame]
Darryl Greendb2b8db2018-06-15 13:06:04 +01001/**
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
29extern "C" {
30#endif
31
32/* Include the Mbed TLS configuration file, the way Mbed TLS does it
33 * in each of its header files. */
34#if defined(MBEDTLS_CONFIG_FILE)
35#include MBEDTLS_CONFIG_FILE
36#else
37#include "mbedtls/config.h"
38#endif
39
40#include "psa/crypto.h"
41#include <stdint.h>
Gilles Peskinec8336cb2019-07-22 19:26:12 +020042#include <string.h>
Darryl Greendb2b8db2018-06-15 13:06:04 +010043
44/* Limit the maximum key size to 30kB (just in case someone tries to
45 * inadvertently store an obscene amount of data) */
46#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 )
47
Gilles Peskine48868122018-12-10 17:30:29 +010048/** The maximum permitted persistent slot number.
49 *
50 * In Mbed Crypto 0.1.0b:
51 * - Using the file backend, all key ids are ok except 0.
52 * - Using the ITS backend, all key ids are ok except 0xFFFFFF52
53 * (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the
54 * device's random seed (if this feature is enabled).
55 * - Only key ids from 1 to #PSA_KEY_SLOT_COUNT are actually used.
56 *
57 * Since we need to preserve the random seed, avoid using that key slot.
58 * Reserve a whole range of key slots just in case something else comes up.
59 *
60 * This limitation will probably become moot when we implement client
61 * separation for key storage.
62 */
Gilles Peskinef9666592019-05-06 18:56:30 +020063#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX
Gilles Peskine48868122018-12-10 17:30:29 +010064
Darryl Greendb2b8db2018-06-15 13:06:04 +010065/**
Gilles Peskine5e80d912019-02-24 17:10:18 +010066 * \brief Checks if persistent data is stored for the given key slot number
67 *
68 * This function checks if any key data or metadata exists for the key slot in
69 * the persistent storage.
70 *
71 * \param key Persistent identifier to check.
72 *
73 * \retval 0
74 * No persistent data present for slot number
75 * \retval 1
76 * Persistent data present for slot number
77 */
78int psa_is_key_present_in_storage( const psa_key_file_id_t key );
79
80/**
Darryl Greendb2b8db2018-06-15 13:06:04 +010081 * \brief Format key data and metadata and save to a location for given key
82 * slot.
83 *
84 * This function formats the key data and metadata and saves it to a
85 * persistent storage backend. The storage location corresponding to the
86 * key slot must be empty, otherwise this function will fail. This function
87 * should be called after psa_import_key_into_slot() to ensure the
88 * persistent key is not saved into a storage location corresponding to an
89 * already occupied non-persistent key, as well as validating the key data.
90 *
91 *
Gilles Peskine8d4919b2018-12-03 16:48:09 +010092 * \param key Persistent identifier of the key to be stored. This
93 * should be an unoccupied storage location.
Darryl Greendb2b8db2018-06-15 13:06:04 +010094 * \param type Key type (a \c PSA_KEY_TYPE_XXX value).
95 * \param[in] policy The key policy to save.
96 * \param[in] data Buffer containing the key data.
97 * \param data_length The number of bytes that make up the key data.
98 *
99 * \retval PSA_SUCCESS
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100100 * \retval PSA_ERROR_INSUFFICIENT_MEMORY
Darryl Greendb2b8db2018-06-15 13:06:04 +0100101 * \retval PSA_ERROR_INSUFFICIENT_STORAGE
102 * \retval PSA_ERROR_STORAGE_FAILURE
David Saadab4ecc272019-02-14 13:48:10 +0200103 * \retval PSA_ERROR_ALREADY_EXISTS
Darryl Greendb2b8db2018-06-15 13:06:04 +0100104 */
Gilles Peskine5b229a02019-02-19 13:24:37 +0100105psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
Darryl Greendb2b8db2018-06-15 13:06:04 +0100106 const psa_key_type_t type,
107 const psa_key_policy_t *policy,
108 const uint8_t *data,
109 const size_t data_length );
110
111/**
112 * \brief Parses key data and metadata and load persistent key for given
113 * key slot number.
114 *
115 * This function reads from a storage backend, parses the key data and
116 * metadata and writes them to the appropriate output parameters.
117 *
118 * Note: This function allocates a buffer and returns a pointer to it through
119 * the data parameter. psa_free_persistent_key_data() must be called after
120 * this function to zeroize and free this buffer, regardless of whether this
121 * function succeeds or fails.
122 *
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100123 * \param key Persistent identifier of the key to be loaded. This
124 * should be an occupied storage location.
Darryl Greendb2b8db2018-06-15 13:06:04 +0100125 * \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX
126 * value).
127 * \param[out] policy On success, the key's policy.
128 * \param[out] data Pointer to an allocated key data buffer on return.
129 * \param[out] data_length The number of bytes that make up the key data.
130 *
131 * \retval PSA_SUCCESS
132 * \retval PSA_ERROR_INSUFFICIENT_MEMORY
133 * \retval PSA_ERROR_STORAGE_FAILURE
David Saadab4ecc272019-02-14 13:48:10 +0200134 * \retval PSA_ERROR_DOES_NOT_EXIST
Darryl Greendb2b8db2018-06-15 13:06:04 +0100135 */
Gilles Peskine5b229a02019-02-19 13:24:37 +0100136psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
Darryl Greendb2b8db2018-06-15 13:06:04 +0100137 psa_key_type_t *type,
138 psa_key_policy_t *policy,
139 uint8_t **data,
140 size_t *data_length );
141
142/**
143 * \brief Remove persistent data for the given key slot number.
144 *
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100145 * \param key Persistent identifier of the key to remove
Darryl Greendb2b8db2018-06-15 13:06:04 +0100146 * from persistent storage.
147 *
148 * \retval PSA_SUCCESS
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100149 * The key was successfully removed,
150 * or the key did not exist.
Darryl Greendb2b8db2018-06-15 13:06:04 +0100151 * \retval PSA_ERROR_STORAGE_FAILURE
152 */
Gilles Peskine5b229a02019-02-19 13:24:37 +0100153psa_status_t psa_destroy_persistent_key( const psa_key_file_id_t key );
Darryl Greendb2b8db2018-06-15 13:06:04 +0100154
155/**
Gilles Peskine8d4919b2018-12-03 16:48:09 +0100156 * \brief Free the temporary buffer allocated by psa_load_persistent_key().
Darryl Greendb2b8db2018-06-15 13:06:04 +0100157 *
158 * This function must be called at some point after psa_load_persistent_key()
159 * to zeroize and free the memory allocated to the buffer in that function.
160 *
161 * \param key_data Buffer for the key data.
162 * \param key_data_length Size of the key data buffer.
163 *
164 */
165void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length );
166
167/**
168 * \brief Formats key data and metadata for persistent storage
169 *
170 * \param[in] data Buffer for the key data.
171 * \param data_length Length of the key data buffer.
172 * \param type Key type (a \c PSA_KEY_TYPE_XXX value).
173 * \param policy The key policy.
174 * \param[out] storage_data Output buffer for the formatted data.
175 *
176 */
177void psa_format_key_data_for_storage( const uint8_t *data,
178 const size_t data_length,
179 const psa_key_type_t type,
180 const psa_key_policy_t *policy,
181 uint8_t *storage_data );
182
183/**
184 * \brief Parses persistent storage data into key data and metadata
185 *
186 * \param[in] storage_data Buffer for the storage data.
187 * \param storage_data_length Length of the storage data buffer
188 * \param[out] key_data On output, pointer to a newly allocated buffer
189 * containing the key data. This must be freed
190 * using psa_free_persistent_key_data()
191 * \param[out] key_data_length Length of the key data buffer
192 * \param[out] type Key type (a \c PSA_KEY_TYPE_XXX value).
193 * \param[out] policy The key policy.
194 *
195 * \retval PSA_SUCCESS
196 * \retval PSA_ERROR_INSUFFICIENT_STORAGE
197 * \retval PSA_ERROR_INSUFFICIENT_MEMORY
198 * \retval PSA_ERROR_STORAGE_FAILURE
199 */
200psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
201 size_t storage_data_length,
202 uint8_t **key_data,
203 size_t *key_data_length,
204 psa_key_type_t *type,
205 psa_key_policy_t *policy );
206
Gilles Peskinec8336cb2019-07-22 19:26:12 +0200207#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
208/** This symbol is defined if transaction support is required. */
209#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS
210#endif
211
212#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
213
214/** The type of transaction that is in progress.
215 */
216/* This is an integer type rather than an enum for two reasons: to support
217 * unknown values when loading a transaction file, and to ensure that the
218 * type has a known size.
219 */
220typedef uint16_t psa_crypto_transaction_type_t;
221
222/** No transaction is in progress.
223 */
224#define PSA_CRYPTO_TRANSACTION_NONE ( (psa_crypto_transaction_type_t) 0x0000 )
225
226/** Transaction data.
227 *
228 * This type is designed to be serialized by writing the memory representation
229 * and reading it back on the same device.
230 *
231 * \note The transaction mechanism is designed for a single active transaction
232 * at a time. The transaction object is #psa_crypto_transaction.
233 *
234 * \note If an API call starts a transaction, it must complete this transaction
235 * before returning to the application.
236 *
237 * The lifetime of a transaction is the following (note that only one
238 * transaction may be active at a time):
239 *
240 * -# Call psa_crypto_prepare_transaction() to initialize the transaction
241 * object in memory and declare the type of transaction that is starting.
242 * -# Fill in the type-specific fields of #psa_crypto_transaction.
243 * -# Call psa_crypto_save_transaction() to start the transaction. This
244 * saves the transaction data to internal storage.
245 * -# If there are intermediate stages in the transaction, update
246 * the fields of #psa_crypto_transaction and call
247 * psa_crypto_save_transaction() again when each stage is reached.
248 * -# When the transaction is over, whether it has been committed or aborted,
249 * call psa_crypto_stop_transaction() to remove the transaction data in
250 * storage and in memory.
251 *
252 * If the system crashes while a transaction is in progress, psa_crypto_init()
253 * calls psa_crypto_load_transaction() and takes care of completing or
254 * rewinding the transaction.
255 */
256typedef union
257{
258 /* Each element of this union must have the following properties
259 * to facilitate serialization and deserialization:
260 *
261 * - The element is a struct.
262 * - The first field of the struct is `psa_crypto_transaction_type_t type`.
263 * - Elements of the struct are arranged such a way that there is
264 * no padding.
265 */
266 struct psa_crypto_transaction_unknown_s
267 {
268 psa_crypto_transaction_type_t type;
269 } unknown;
270} psa_crypto_transaction_t;
271
272/** The single active transaction.
273 */
274extern psa_crypto_transaction_t psa_crypto_transaction;
275
276/** Prepare for a transaction.
277 *
278 * There must not be an ongoing transaction.
279 *
280 * \param type The type of transaction to start.
281 */
282static inline void psa_crypto_prepare_transaction(
283 psa_crypto_transaction_type_t type )
284{
285 psa_crypto_transaction.unknown.type = type;
286}
287
288/** Save the transaction data to storage.
289 *
290 * You may call this function multiple times during a transaction to
291 * atomically update the transaction state.
292 *
293 * \retval #PSA_SUCCESS
294 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
295 * \retval #PSA_ERROR_STORAGE_FAILURE
296 */
297psa_status_t psa_crypto_save_transaction( void );
298
299/** Load the transaction data from storage, if any.
300 *
301 * This function is meant to be called from psa_crypto_init() to recover
302 * in case a transaction was interrupted by a system crash.
303 *
304 * \retval #PSA_SUCCESS
305 * The data about the ongoing transaction has been loaded to
306 * #psa_crypto_transaction.
307 * \retval #PSA_ERROR_DOES_NOT_EXIST
308 * There is no ongoing transaction.
309 * \retval #PSA_ERROR_STORAGE_FAILURE
310 */
311psa_status_t psa_crypto_load_transaction( void );
312
313/** Indicate that the current transaction is finished.
314 *
315 * Call this function at the very end of transaction processing, whether
316 * the transaction has been committed or aborted.
317 *
318 * This function erases the transaction data in storage (if any) and
319 * resets the transaction data in memory.
320 *
321 * \retval #PSA_SUCCESS
322 * There was transaction data in storage.
323 * \retval #PSA_ERROR_DOES_NOT_EXIST
324 * There was no transaction data in storage.
325 * \retval #PSA_ERROR_STORAGE_FAILURE
326 * It was impossible to determine whether there was transaction data
327 * in storage, or the transaction data could not be erased.
328 */
329psa_status_t psa_crypto_stop_transaction( void );
330
331/** The ITS file identifier for the transaction data.
332 *
333 * 0xffffffNN = special file; 0x74 = 't' for transaction.
334 */
335#define PSA_CRYPTO_ITS_TRANSACTION_UID ( (psa_key_id_t) 0xffffff74 )
336
337#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
338
Gilles Peskinee3dbdd82019-02-25 11:04:06 +0100339#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
340/** Backend side of mbedtls_psa_inject_entropy().
341 *
342 * This function stores the supplied data into the entropy seed file.
343 *
344 * \retval #PSA_SUCCESS
345 * Success
346 * \retval #PSA_ERROR_STORAGE_FAILURE
347 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
348 * \retval #PSA_ERROR_NOT_PERMITTED
349 * The entropy seed file already exists.
350 */
351psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
352 size_t seed_size );
353#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
354
Darryl Greendb2b8db2018-06-15 13:06:04 +0100355#ifdef __cplusplus
356}
357#endif
358
359#endif /* PSA_CRYPTO_STORAGE_H */