Merge pull request #2747 from Eltrick/stylise-dormakaba
[RRG-proxmark3.git] / common / mbedtls / psa_crypto_storage.c
blobc013366f8aea2cfeeeb15e4d6ea546f777a28cbb
1 /*
2 * PSA persistent key storage
3 */
4 /*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #if defined(MBEDTLS_CONFIG_FILE)
22 #include MBEDTLS_CONFIG_FILE
23 #else
24 #include "mbedtls/config.h"
25 #endif
27 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
29 #include <stdlib.h>
30 #include <string.h>
32 #include "psa_crypto_service_integration.h"
33 #include "psa/crypto.h"
34 #include "psa_crypto_storage.h"
35 #include "mbedtls/platform_util.h"
37 #if defined(MBEDTLS_PSA_ITS_FILE_C)
38 #include "psa_crypto_its.h"
39 #else /* Native ITS implementation */
40 #include "psa/error.h"
41 #include "psa/internal_trusted_storage.h"
42 #endif
44 #if defined(MBEDTLS_PLATFORM_C)
45 #include "mbedtls/platform.h"
46 #else
47 #include <stdlib.h>
48 #define mbedtls_calloc calloc
49 #define mbedtls_free free
50 #endif
54 /****************************************************************/
55 /* Key storage */
56 /****************************************************************/
58 /* Determine a file name (ITS file identifier) for the given key identifier.
59 * The file name must be distinct from any file that is used for a purpose
60 * other than storing a key. Currently, the only such file is the random seed
61 * file whose name is PSA_CRYPTO_ITS_RANDOM_SEED_UID and whose value is
62 * 0xFFFFFF52. */
63 static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key) {
64 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
65 /* Encode the owner in the upper 32 bits. This means that if
66 * owner values are nonzero (as they are on a PSA platform),
67 * no key file will ever have a value less than 0x100000000, so
68 * the whole range 0..0xffffffff is available for non-key files. */
69 uint32_t unsigned_owner_id = MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key);
70 return (((uint64_t) unsigned_owner_id << 32) |
71 MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key));
72 #else
73 /* Use the key id directly as a file name.
74 * psa_is_key_id_valid() in psa_crypto_slot_management.c
75 * is responsible for ensuring that key identifiers do not have a
76 * value that is reserved for non-key files. */
77 return (key);
78 #endif
81 /**
82 * \brief Load persistent data for the given key slot number.
84 * This function reads data from a storage backend and returns the data in a
85 * buffer.
87 * \param key Persistent identifier of the key to be loaded. This
88 * should be an occupied storage location.
89 * \param[out] data Buffer where the data is to be written.
90 * \param data_size Size of the \c data buffer in bytes.
92 * \retval #PSA_SUCCESS
93 * \retval #PSA_ERROR_DATA_INVALID
94 * \retval #PSA_ERROR_DATA_CORRUPT
95 * \retval #PSA_ERROR_STORAGE_FAILURE
96 * \retval #PSA_ERROR_DOES_NOT_EXIST
98 static psa_status_t psa_crypto_storage_load(
99 const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size) {
100 psa_status_t status;
101 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
102 struct psa_storage_info_t data_identifier_info;
103 size_t data_length = 0;
105 status = psa_its_get_info(data_identifier, &data_identifier_info);
106 if (status != PSA_SUCCESS)
107 return (status);
109 status = psa_its_get(data_identifier, 0, (uint32_t) data_size, data, &data_length);
110 if (data_size != data_length)
111 return (PSA_ERROR_DATA_INVALID);
113 return (status);
116 int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key) {
117 psa_status_t ret;
118 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
119 struct psa_storage_info_t data_identifier_info;
121 ret = psa_its_get_info(data_identifier, &data_identifier_info);
123 if (ret == PSA_ERROR_DOES_NOT_EXIST)
124 return (0);
125 return (1);
129 * \brief Store persistent data for the given key slot number.
131 * This function stores the given data buffer to a persistent storage.
133 * \param key Persistent identifier of the key to be stored. This
134 * should be an unoccupied storage location.
135 * \param[in] data Buffer containing the data to be stored.
136 * \param data_length The number of bytes
137 * that make up the data.
139 * \retval #PSA_SUCCESS
140 * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
141 * \retval #PSA_ERROR_ALREADY_EXISTS
142 * \retval #PSA_ERROR_STORAGE_FAILURE
143 * \retval #PSA_ERROR_DATA_INVALID
145 static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key,
146 const uint8_t *data,
147 size_t data_length) {
148 psa_status_t status;
149 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
150 struct psa_storage_info_t data_identifier_info;
152 if (psa_is_key_present_in_storage(key) == 1)
153 return (PSA_ERROR_ALREADY_EXISTS);
155 status = psa_its_set(data_identifier, (uint32_t) data_length, data, 0);
156 if (status != PSA_SUCCESS) {
157 return (PSA_ERROR_DATA_INVALID);
160 status = psa_its_get_info(data_identifier, &data_identifier_info);
161 if (status != PSA_SUCCESS) {
162 goto exit;
165 if (data_identifier_info.size != data_length) {
166 status = PSA_ERROR_DATA_INVALID;
167 goto exit;
170 exit:
171 if (status != PSA_SUCCESS) {
172 /* Remove the file in case we managed to create it but something
173 * went wrong. It's ok if the file doesn't exist. If the file exists
174 * but the removal fails, we're already reporting an error so there's
175 * nothing else we can do. */
176 (void) psa_its_remove(data_identifier);
178 return (status);
181 psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key) {
182 psa_status_t ret;
183 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
184 struct psa_storage_info_t data_identifier_info;
186 ret = psa_its_get_info(data_identifier, &data_identifier_info);
187 if (ret == PSA_ERROR_DOES_NOT_EXIST)
188 return (PSA_SUCCESS);
190 if (psa_its_remove(data_identifier) != PSA_SUCCESS)
191 return (PSA_ERROR_DATA_INVALID);
193 ret = psa_its_get_info(data_identifier, &data_identifier_info);
194 if (ret != PSA_ERROR_DOES_NOT_EXIST)
195 return (PSA_ERROR_DATA_INVALID);
197 return (PSA_SUCCESS);
201 * \brief Get data length for given key slot number.
203 * \param key Persistent identifier whose stored data length
204 * is to be obtained.
205 * \param[out] data_length The number of bytes that make up the data.
207 * \retval #PSA_SUCCESS
208 * \retval #PSA_ERROR_STORAGE_FAILURE
209 * \retval #PSA_ERROR_DOES_NOT_EXIST
210 * \retval #PSA_ERROR_DATA_CORRUPT
212 static psa_status_t psa_crypto_storage_get_data_length(
213 const mbedtls_svc_key_id_t key,
214 size_t *data_length) {
215 psa_status_t status;
216 psa_storage_uid_t data_identifier = psa_its_identifier_of_slot(key);
217 struct psa_storage_info_t data_identifier_info;
219 status = psa_its_get_info(data_identifier, &data_identifier_info);
220 if (status != PSA_SUCCESS)
221 return (status);
223 *data_length = (size_t) data_identifier_info.size;
225 return (PSA_SUCCESS);
229 * 32-bit integer manipulation macros (little endian)
231 #ifndef GET_UINT32_LE
232 #define GET_UINT32_LE( n, b, i ) \
234 (n) = ( (uint32_t) (b)[(i) ] ) \
235 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
236 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
237 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
239 #endif
241 #ifndef PUT_UINT32_LE
242 #define PUT_UINT32_LE( n, b, i ) \
244 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
245 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
246 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
247 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
249 #endif
252 * 16-bit integer manipulation macros (little endian)
254 #ifndef GET_UINT16_LE
255 #define GET_UINT16_LE( n, b, i ) \
257 (n) = ( (uint16_t) (b)[(i) ] ) \
258 | ( (uint16_t) (b)[(i) + 1] << 8 ); \
260 #endif
262 #ifndef PUT_UINT16_LE
263 #define PUT_UINT16_LE( n, b, i ) \
265 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
266 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
268 #endif
271 * Persistent key storage magic header.
273 #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
274 #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) )
276 typedef struct {
277 uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
278 uint8_t version[4];
279 uint8_t lifetime[sizeof(psa_key_lifetime_t)];
280 uint8_t type[2];
281 uint8_t bits[2];
282 uint8_t policy[sizeof(psa_key_policy_t)];
283 uint8_t data_len[4];
284 uint8_t key_data[];
285 } psa_persistent_key_storage_format;
287 void psa_format_key_data_for_storage(const uint8_t *data,
288 const size_t data_length,
289 const psa_core_key_attributes_t *attr,
290 uint8_t *storage_data) {
291 psa_persistent_key_storage_format *storage_format =
292 (psa_persistent_key_storage_format *) storage_data;
294 memcpy(storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH);
295 PUT_UINT32_LE(0, storage_format->version, 0);
296 PUT_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
297 PUT_UINT16_LE((uint16_t) attr->type, storage_format->type, 0);
298 PUT_UINT16_LE((uint16_t) attr->bits, storage_format->bits, 0);
299 PUT_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
300 PUT_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
301 PUT_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
302 PUT_UINT32_LE(data_length, storage_format->data_len, 0);
303 memcpy(storage_format->key_data, data, data_length);
306 static psa_status_t check_magic_header(const uint8_t *data) {
307 if (memcmp(data, PSA_KEY_STORAGE_MAGIC_HEADER,
308 PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH) != 0)
309 return (PSA_ERROR_DATA_INVALID);
310 return (PSA_SUCCESS);
313 psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data,
314 size_t storage_data_length,
315 uint8_t **key_data,
316 size_t *key_data_length,
317 psa_core_key_attributes_t *attr) {
318 psa_status_t status;
319 const psa_persistent_key_storage_format *storage_format =
320 (const psa_persistent_key_storage_format *)storage_data;
321 uint32_t version;
323 if (storage_data_length < sizeof(*storage_format))
324 return (PSA_ERROR_DATA_INVALID);
326 status = check_magic_header(storage_data);
327 if (status != PSA_SUCCESS)
328 return (status);
330 GET_UINT32_LE(version, storage_format->version, 0);
331 if (version != 0)
332 return (PSA_ERROR_DATA_INVALID);
334 GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
335 if (*key_data_length > (storage_data_length - sizeof(*storage_format)) ||
336 *key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE)
337 return (PSA_ERROR_DATA_INVALID);
339 if (*key_data_length == 0) {
340 *key_data = NULL;
341 } else {
342 *key_data = mbedtls_calloc(1, *key_data_length);
343 if (*key_data == NULL)
344 return (PSA_ERROR_INSUFFICIENT_MEMORY);
345 memcpy(*key_data, storage_format->key_data, *key_data_length);
348 GET_UINT32_LE(attr->lifetime, storage_format->lifetime, 0);
349 GET_UINT16_LE(attr->type, storage_format->type, 0);
350 GET_UINT16_LE(attr->bits, storage_format->bits, 0);
351 GET_UINT32_LE(attr->policy.usage, storage_format->policy, 0);
352 GET_UINT32_LE(attr->policy.alg, storage_format->policy, sizeof(uint32_t));
353 GET_UINT32_LE(attr->policy.alg2, storage_format->policy, 2 * sizeof(uint32_t));
355 return (PSA_SUCCESS);
358 psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr,
359 const uint8_t *data,
360 const size_t data_length) {
361 size_t storage_data_length;
362 uint8_t *storage_data;
363 psa_status_t status;
365 /* All keys saved to persistent storage always have a key context */
366 if (data == NULL || data_length == 0)
367 return (PSA_ERROR_INVALID_ARGUMENT);
369 if (data_length > PSA_CRYPTO_MAX_STORAGE_SIZE)
370 return (PSA_ERROR_INSUFFICIENT_STORAGE);
371 storage_data_length = data_length + sizeof(psa_persistent_key_storage_format);
373 storage_data = mbedtls_calloc(1, storage_data_length);
374 if (storage_data == NULL)
375 return (PSA_ERROR_INSUFFICIENT_MEMORY);
377 psa_format_key_data_for_storage(data, data_length, attr, storage_data);
379 status = psa_crypto_storage_store(attr->id,
380 storage_data, storage_data_length);
382 mbedtls_free(storage_data);
384 return (status);
387 void psa_free_persistent_key_data(uint8_t *key_data, size_t key_data_length) {
388 if (key_data != NULL) {
389 mbedtls_platform_zeroize(key_data, key_data_length);
391 mbedtls_free(key_data);
394 psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr,
395 uint8_t **data,
396 size_t *data_length) {
397 psa_status_t status = PSA_SUCCESS;
398 uint8_t *loaded_data;
399 size_t storage_data_length = 0;
400 mbedtls_svc_key_id_t key = attr->id;
402 status = psa_crypto_storage_get_data_length(key, &storage_data_length);
403 if (status != PSA_SUCCESS)
404 return (status);
406 loaded_data = mbedtls_calloc(1, storage_data_length);
408 if (loaded_data == NULL)
409 return (PSA_ERROR_INSUFFICIENT_MEMORY);
411 status = psa_crypto_storage_load(key, loaded_data, storage_data_length);
412 if (status != PSA_SUCCESS)
413 goto exit;
415 status = psa_parse_key_data_from_storage(loaded_data, storage_data_length,
416 data, data_length, attr);
418 /* All keys saved to persistent storage always have a key context */
419 if (status == PSA_SUCCESS &&
420 (*data == NULL || *data_length == 0))
421 status = PSA_ERROR_STORAGE_FAILURE;
423 exit:
424 mbedtls_free(loaded_data);
425 return (status);
430 /****************************************************************/
431 /* Transactions */
432 /****************************************************************/
434 #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
436 psa_crypto_transaction_t psa_crypto_transaction;
438 psa_status_t psa_crypto_save_transaction(void) {
439 struct psa_storage_info_t p_info;
440 psa_status_t status;
441 status = psa_its_get_info(PSA_CRYPTO_ITS_TRANSACTION_UID, &p_info);
442 if (status == PSA_SUCCESS) {
443 /* This shouldn't happen: we're trying to start a transaction while
444 * there is still a transaction that hasn't been replayed. */
445 return (PSA_ERROR_CORRUPTION_DETECTED);
446 } else if (status != PSA_ERROR_DOES_NOT_EXIST)
447 return (status);
448 return (psa_its_set(PSA_CRYPTO_ITS_TRANSACTION_UID,
449 sizeof(psa_crypto_transaction),
450 &psa_crypto_transaction,
451 0));
454 psa_status_t psa_crypto_load_transaction(void) {
455 psa_status_t status;
456 size_t length;
457 status = psa_its_get(PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
458 sizeof(psa_crypto_transaction),
459 &psa_crypto_transaction, &length);
460 if (status != PSA_SUCCESS)
461 return (status);
462 if (length != sizeof(psa_crypto_transaction))
463 return (PSA_ERROR_DATA_INVALID);
464 return (PSA_SUCCESS);
467 psa_status_t psa_crypto_stop_transaction(void) {
468 psa_status_t status = psa_its_remove(PSA_CRYPTO_ITS_TRANSACTION_UID);
469 /* Whether or not updating the storage succeeded, the transaction is
470 * finished now. It's too late to go back, so zero out the in-memory
471 * data. */
472 memset(&psa_crypto_transaction, 0, sizeof(psa_crypto_transaction));
473 return (status);
476 #endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
480 /****************************************************************/
481 /* Random generator state */
482 /****************************************************************/
484 #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
485 psa_status_t mbedtls_psa_storage_inject_entropy(const unsigned char *seed,
486 size_t seed_size) {
487 psa_status_t status;
488 struct psa_storage_info_t p_info;
490 status = psa_its_get_info(PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info);
492 if (PSA_ERROR_DOES_NOT_EXIST == status) { /* No seed exists */
493 status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID, seed_size, seed, 0);
494 } else if (PSA_SUCCESS == status) {
495 /* You should not be here. Seed needs to be injected only once */
496 status = PSA_ERROR_NOT_PERMITTED;
498 return (status);
500 #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
504 /****************************************************************/
505 /* The end */
506 /****************************************************************/
508 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */