1 /*
2 * PSA persistent key storage
3 */
4 /*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7 */
8
9 #include "common.h"
10
11 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "psa/crypto.h"
17 #include "psa_crypto_storage.h"
18 #include "mbedtls/platform_util.h"
19
20 #if defined(MBEDTLS_PSA_ITS_FILE_C)
21 #include "psa_crypto_its.h"
22 #else /* Native ITS implementation */
23 #include "psa/error.h"
24 #include "psa/internal_trusted_storage.h"
25 #endif
26
27 #include "mbedtls/platform.h"
28
29 /****************************************************************/
30 /* Key storage */
31 /****************************************************************/
32
33 /* Determine a file name (ITS file identifier) for the given key identifier.
34 * The file name must be distinct from any file that is used for a purpose
35 * other than storing a key. Currently, the only such file is the random seed
36 * file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is
37 * 0xFFFFFF52. */
psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)38 static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key)
39 {
40 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
41 /* Encode the owner in the upper 32 bits. This means that if
42 * owner values are nonzero (as they are on a PSA platform),
43 * no key file will ever have a value less than 0x100000000, so
44 * the whole range 0..0xffffffff is available for non-key files. */
45 uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key);
46 return ((uint64_t) unsigned_owner_id << 32) |
47 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key);
48 #else
49 /* Use the key id directly as a file name.
50 * psa_is_key_id_valid() in psa_crypto_slot_management.c
51 * is responsible for ensuring that key identifiers do not have a
52 * value that is reserved for non-key files. */
53 return key;
54 #endif
55 }
56
57 /**
58 * \brief Load persistent data for the given key slot number.
59 *
60 * This function reads data from a storage backend and returns the data in a
61 * buffer.
62 *
63 * \param key Persistent identifier of the key to be loaded. This
64 * should be an occupied storage location.
65 * \param[out] data Buffer where the data is to be written.
66 * \param data_size Size of the \c data buffer in bytes.
67 *
68 * \retval #PSA_SUCCESS \emptydescription
69 * \retval #PSA_ERROR_DATA_INVALID \emptydescription
70 * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
71 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
72 * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
73 */
psa_crypto_storage_load(const mbedtls_svc_key_id_t key,uint8_t * data,size_t data_size)74 static psa_status_t psa_crypto_storage_load(
75 const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size)
76 {
77 psa_status_t status;
78 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
79 struct psa_storage_info_t data_identifier_info;
80 size_t data_length = 0;
81
82 status = psa_its_get_info(data_identifier, &data_identifier_info);
83 if (status != PSA_SUCCESS) {
84 return status;
85 }
86
87 status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length);
88 if (data_size != data_length) {
89 return PSA_ERROR_DATA_INVALID;
90 }
91
92 return status;
93 }
94
psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)95 int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key)
96 {
97 psa_status_t ret;
98 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
99 struct psa_storage_info_t data_identifier_info;
100
101 ret = psa_its_get_info(data_identifier, &data_identifier_info);
102
103 if (ret == PSA_ERROR_DOES_NOT_EXIST) {
104 return 0;
105 }
106 return 1;
107 }
108
109 /**
110 * \brief Store persistent data for the given key slot number.
111 *
112 * This function stores the given data buffer to a persistent storage.
113 *
114 * \param key Persistent identifier of the key to be stored. This
115 * should be an unoccupied storage location.
116 * \param[in] data Buffer containing the data to be stored.
117 * \param data_length The number of bytes
118 * that make up the data.
119 *
120 * \retval #PSA_SUCCESS \emptydescription
121 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription
122 * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription
123 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
124 * \retval #PSA_ERROR_DATA_INVALID \emptydescription
125 */
psa_crypto_storage_store(const mbedtls_svc_key_id_t key,const uint8_t * data,size_t data_length)126 static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
127 const uint8_t *data,
128 size_t data_length)
129 {
130 psa_status_t status;
131 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
132 struct psa_storage_info_t data_identifier_info;
133
134 if (psa_is_key_present_in_storage(key) == 1) {
135 return PSA_ERROR_ALREADY_EXISTS;
136 }
137
138 status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0);
139 if (status != PSA_SUCCESS) {
140 return PSA_ERROR_DATA_INVALID;
141 }
142
143 status = psa_its_get_info(data_identifier, &data_identifier_info);
144 if (status != PSA_SUCCESS) {
145 goto exit;
146 }
147
148 if (data_identifier_info.size != data_length) {
149 status = PSA_ERROR_DATA_INVALID;
150 goto exit;
151 }
152
153 exit:
154 if (status != PSA_SUCCESS) {
155 /* Remove the file in case we managed to create it but something
156 * went wrong. It's ok if the file doesn't exist. If the file exists
157 * but the removal fails, we're already reporting an error so there's
158 * nothing else we can do. */
159 (void) psa_its_remove(data_identifier);
160 }
161 return status;
162 }
163
psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)164 psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key)
165 {
166 psa_status_t ret;
167 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
168 struct psa_storage_info_t data_identifier_info;
169
170 ret = psa_its_get_info(data_identifier, &data_identifier_info);
171 if (ret == PSA_ERROR_DOES_NOT_EXIST) {
172 return PSA_SUCCESS;
173 }
174
175 if (psa_its_remove(data_identifier) != PSA_SUCCESS) {
176 return PSA_ERROR_DATA_INVALID;
177 }
178
179 ret = psa_its_get_info(data_identifier, &data_identifier_info);
180 if (ret != PSA_ERROR_DOES_NOT_EXIST) {
181 return PSA_ERROR_DATA_INVALID;
182 }
183
184 return PSA_SUCCESS;
185 }
186
187 /**
188 * \brief Get data length for given key slot number.
189 *
190 * \param key Persistent identifier whose stored data length
191 * is to be obtained.
192 * \param[out] data_length The number of bytes that make up the data.
193 *
194 * \retval #PSA_SUCCESS \emptydescription
195 * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription
196 * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription
197 * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription
198 */
psa_crypto_storage_get_data_length(const mbedtls_svc_key_id_t key,size_t * data_length)199 static psa_status_t psa_crypto_storage_get_data_length(
200 const mbedtls_svc_key_id_t key,
201 size_t *data_length)
202 {
203 psa_status_t status;
204 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
205 struct psa_storage_info_t data_identifier_info;
206
207 status = psa_its_get_info(data_identifier, &data_identifier_info);
208 if (status != PSA_SUCCESS) {
209 return status;
210 }
211
212 *data_length = (size_t) data_identifier_info.size;
213
214 return PSA_SUCCESS;
215 }
216
217 /**
218 * Persistent key storage magic header.
219 */
220 #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
221 #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
222
223 typedef struct {
224 uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
225 uint8_t version[4];
226 uint8_t lifetime[sizeof(psa_key_lifetime_t)];
227 uint8_t type[2];
228 uint8_t bits[2];
229 uint8_t policy[sizeof(psa_key_policy_t)];
230 uint8_t data_len[4];
231 uint8_t key_data[];
232 } psa_persistent_key_storage_format;
233
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)234 void psa_format_key_data_for_storage(const uint8_t *data,
235 const size_t data_length,
236 const psa_core_key_attributes_t *attr,
237 uint8_t *storage_data)
238 {
239 psa_persistent_key_storage_format *storage_format =
240 (psa_persistent_key_storage_format *) storage_data;
241
242 memcpy(storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER,
243 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH);
244 MBEDTLS_PUT_UINT32_LE(0, storage_format->version, 0);
245 MBEDTLS_PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
246 MBEDTLS_PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0);
247 MBEDTLS_PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0);
248 MBEDTLS_PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
249 MBEDTLS_PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
250 MBEDTLS_PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
251 MBEDTLS_PUT_UINT32_LE(data_length, storage_format->data_len, 0);
252 memcpy(storage_format->key_data, data, data_length);
253 }
254
check_magic_header(const uint8_t * data)255 static psa_status_t check_magic_header(const uint8_t *data)
256 {
257 if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER,
258 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0) {
259 return PSA_ERROR_DATA_INVALID;
260 }
261 return PSA_SUCCESS;
262 }
263
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)264 psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
265 size_t storage_data_length,
266 uint8_t **key_data,
267 size_t *key_data_length,
268 psa_core_key_attributes_t *attr)
269 {
270 psa_status_t status;
271 const psa_persistent_key_storage_format *storage_format =
272 (const psa_persistent_key_storage_format *) storage_data;
273 uint32_t version;
274
275 if (storage_data_length < sizeof(*storage_format)) {
276 return PSA_ERROR_DATA_INVALID;
277 }
278
279 status = check_magic_header(storage_data);
280 if (status != PSA_SUCCESS) {
281 return status;
282 }
283
284 version = MBEDTLS_GET_UINT32_LE(storage_format->version, 0);
285 if (version != 0) {
286 return PSA_ERROR_DATA_INVALID;
287 }
288
289 *key_data_length = MBEDTLS_GET_UINT32_LE(storage_format->data_len, 0);
290 if (*key_data_length > (storage_data_length - sizeof(*storage_format)) ||
291 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
292 return PSA_ERROR_DATA_INVALID;
293 }
294
295 if (*key_data_length == 0) {
296 *key_data = NULL;
297 } else {
298 *key_data = mbedtls_calloc(1, *key_data_length);
299 if (*key_data == NULL) {
300 return PSA_ERROR_INSUFFICIENT_MEMORY;
301 }
302 memcpy(*key_data, storage_format->key_data, *key_data_length);
303 }
304
305 attr->lifetime = MBEDTLS_GET_UINT32_LE(storage_format->lifetime, 0);
306 attr->type = MBEDTLS_GET_UINT16_LE(storage_format->type, 0);
307 attr->bits = MBEDTLS_GET_UINT16_LE(storage_format->bits, 0);
308 attr->policy.usage = MBEDTLS_GET_UINT32_LE(storage_format->policy, 0);
309 attr->policy.alg = MBEDTLS_GET_UINT32_LE(storage_format->policy, sizeof(uint32_t));
310 attr->policy.alg2 = MBEDTLS_GET_UINT32_LE(storage_format->policy, 2 * sizeof(uint32_t));
311
312 return PSA_SUCCESS;
313 }
314
psa_save_persistent_key(const psa_core_key_attributes_t * attr,const uint8_t * data,const size_t data_length)315 psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
316 const uint8_t *data,
317 const size_t data_length)
318 {
319 size_t storage_data_length;
320 uint8_t *storage_data;
321 psa_status_t status;
322
323 /* All keys saved to persistent storage always have a key context */
324 if (data == NULL || data_length == 0) {
325 return PSA_ERROR_INVALID_ARGUMENT;
326 }
327
328 if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE) {
329 return PSA_ERROR_INSUFFICIENT_STORAGE;
330 }
331 storage_data_length = data_length + sizeof(psa_persistent_key_storage_format);
332
333 storage_data = mbedtls_calloc(1, storage_data_length);
334 if (storage_data == NULL) {
335 return PSA_ERROR_INSUFFICIENT_MEMORY;
336 }
337
338 psa_format_key_data_for_storage(data, data_length, attr, storage_data);
339
340 status = psa_crypto_storage_store(attr->id,
341 storage_data, storage_data_length);
342
343 mbedtls_platform_zeroize(storage_data, storage_data_length);
344 mbedtls_free(storage_data);
345
346 return status;
347 }
348
psa_free_persistent_key_data(uint8_t * key_data,size_t key_data_length)349 void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length)
350 {
351 if (key_data != NULL) {
352 mbedtls_platform_zeroize(key_data, key_data_length);
353 }
354 mbedtls_free(key_data);
355 }
356
psa_load_persistent_key(psa_core_key_attributes_t * attr,uint8_t ** data,size_t * data_length)357 psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
358 uint8_t **data,
359 size_t *data_length)
360 {
361 psa_status_t status = PSA_SUCCESS;
362 uint8_t *loaded_data;
363 size_t storage_data_length = 0;
364 mbedtls_svc_key_id_t key = attr->id;
365
366 status = psa_crypto_storage_get_data_length(key, &storage_data_length);
367 if (status != PSA_SUCCESS) {
368 return status;
369 }
370
371 loaded_data = mbedtls_calloc(1, storage_data_length);
372
373 if (loaded_data == NULL) {
374 return PSA_ERROR_INSUFFICIENT_MEMORY;
375 }
376
377 status = psa_crypto_storage_load(key, loaded_data, storage_data_length);
378 if (status != PSA_SUCCESS) {
379 goto exit;
380 }
381
382 status = psa_parse_key_data_from_storage(loaded_data, storage_data_length,
383 data, data_length, attr);
384
385 /* All keys saved to persistent storage always have a key context */
386 if (status == PSA_SUCCESS &&
387 (*data == NULL || *data_length == 0)) {
388 status = PSA_ERROR_STORAGE_FAILURE;
389 }
390
391 exit:
392 mbedtls_platform_zeroize(loaded_data, storage_data_length);
393 mbedtls_free(loaded_data);
394 return status;
395 }
396
397
398
399 /****************************************************************/
400 /* Transactions */
401 /****************************************************************/
402
403 #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
404
405 psa_crypto_transaction_t psa_crypto_transaction;
406
psa_crypto_save_transaction(void)407 psa_status_t psa_crypto_save_transaction(void)
408 {
409 struct psa_storage_info_t p_info;
410 psa_status_t status;
411 status = psa_its_get_info(PSA_CRYPTO_ITS_TRANSACTION_UID, &p_info);
412 if (status == PSA_SUCCESS) {
413 /* This shouldn't happen: we're trying to start a transaction while
414 * there is still a transaction that hasn't been replayed. */
415 return PSA_ERROR_CORRUPTION_DETECTED;
416 } else if (status != PSA_ERROR_DOES_NOT_EXIST) {
417 return status;
418 }
419 return psa_its_set(PSA_CRYPTO_ITS_TRANSACTION_UID,
420 sizeof(psa_crypto_transaction),
421 &psa_crypto_transaction,
422 0);
423 }
424
psa_crypto_load_transaction(void)425 psa_status_t psa_crypto_load_transaction(void)
426 {
427 psa_status_t status;
428 size_t length;
429 status = psa_its_get(PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
430 sizeof(psa_crypto_transaction),
431 &psa_crypto_transaction, &length);
432 if (status != PSA_SUCCESS) {
433 return status;
434 }
435 if (length != sizeof(psa_crypto_transaction)) {
436 return PSA_ERROR_DATA_INVALID;
437 }
438 return PSA_SUCCESS;
439 }
440
psa_crypto_stop_transaction(void)441 psa_status_t psa_crypto_stop_transaction(void)
442 {
443 psa_status_t status = psa_its_remove(PSA_CRYPTO_ITS_TRANSACTION_UID);
444 /* Whether or not updating the storage succeeded, the transaction is
445 * finished now. It's too late to go back, so zero out the in-memory
446 * data. */
447 memset(&psa_crypto_transaction, 0, sizeof(psa_crypto_transaction));
448 return status;
449 }
450
451 #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
452
453
454
455 /****************************************************************/
456 /* Random generator state */
457 /****************************************************************/
458
459 #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
mbedtls_psa_storage_inject_entropy(const unsigned char * seed,size_t seed_size)460 psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
461 size_t seed_size)
462 {
463 psa_status_t status;
464 struct psa_storage_info_t p_info;
465
466 status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info);
467
468 if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */
469 status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0);
470 } else if (PSA_SUCCESS == status) {
471 /* You should not be here. Seed needs to be injected only once */
472 status = PSA_ERROR_NOT_PERMITTED;
473 }
474 return status;
475 }
476 #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
477
478
479
480 /****************************************************************/
481 /* The end */
482 /****************************************************************/
483
484 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
485