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