quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

psa_crypto_storage.c (16210B)


      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. */
     40 static 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  */
     76 static 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 
     97 int 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  */
    128 static 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 
    155 exit:
    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 
    166 psa_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  */
    201 static 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 
    225 typedef 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 
    236 void 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 
    257 static 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 
    266 psa_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 
    317 psa_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 
    350 void 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 
    355 psa_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 
    389 exit:
    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 
    402 psa_crypto_transaction_t psa_crypto_transaction;
    403 
    404 psa_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 
    422 psa_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 
    438 psa_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)
    457 psa_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 */