quickjs-tart

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

test_suite_psa_crypto_slot_management.function (44814B)


      1 /* BEGIN_HEADER */
      2 #include <stdint.h>
      3 
      4 #include "psa_crypto_slot_management.h"
      5 #include "psa_crypto_storage.h"
      6 
      7 typedef enum {
      8     /**< Close key(s) */
      9     INVALIDATE_BY_CLOSING,
     10 
     11     /**< Destroy key(s) */
     12     INVALIDATE_BY_DESTROYING,
     13 
     14     /**< Purge key(s) */
     15     INVALIDATE_BY_PURGING,
     16 
     17     /**< Terminate and reinitialize without closing/destroying keys */
     18     INVALIDATE_BY_SHUTDOWN,
     19 
     20     /**< Close key(s) then terminate and re-initialize */
     21     INVALIDATE_BY_CLOSING_WITH_SHUTDOWN,
     22 
     23     /**< Destroy key(s) then terminate and re-initialize */
     24     INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN,
     25 
     26     /**< Purge key(s) then terminate and re-initialize */
     27     INVALIDATE_BY_PURGING_WITH_SHUTDOWN,
     28 } invalidate_method_t;
     29 
     30 typedef enum {
     31     KEEP_OPEN,
     32     CLOSE_BEFORE,
     33     CLOSE_AFTER,
     34 } reopen_policy_t;
     35 
     36 typedef enum {
     37     INVALID_HANDLE_0,
     38     INVALID_HANDLE_UNOPENED,
     39     INVALID_HANDLE_CLOSED,
     40     INVALID_HANDLE_HUGE,
     41 } invalid_handle_construction_t;
     42 
     43 /** Apply \p invalidate_method to invalidate the specified key:
     44  * close it, destroy it, or do nothing;
     45  */
     46 static int invalidate_key(invalidate_method_t invalidate_method,
     47                           mbedtls_svc_key_id_t key)
     48 {
     49     switch (invalidate_method) {
     50         /* Closing the key invalidate only volatile keys, not persistent ones. */
     51         case INVALIDATE_BY_CLOSING:
     52         case INVALIDATE_BY_CLOSING_WITH_SHUTDOWN:
     53             PSA_ASSERT(psa_close_key(key));
     54             break;
     55         case INVALIDATE_BY_DESTROYING:
     56         case INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN:
     57             PSA_ASSERT(psa_destroy_key(key));
     58             break;
     59         /* Purging the key just purges RAM data of persistent keys. */
     60         case INVALIDATE_BY_PURGING:
     61         case INVALIDATE_BY_PURGING_WITH_SHUTDOWN:
     62             PSA_ASSERT(psa_purge_key(key));
     63             break;
     64         case INVALIDATE_BY_SHUTDOWN:
     65             break;
     66     }
     67     return 1;
     68 exit:
     69     return 0;
     70 }
     71 
     72 /** Restart the PSA subsystem if \p invalidate_method says so. */
     73 static int invalidate_psa(invalidate_method_t invalidate_method)
     74 {
     75     switch (invalidate_method) {
     76         case INVALIDATE_BY_CLOSING:
     77         case INVALIDATE_BY_DESTROYING:
     78         case INVALIDATE_BY_PURGING:
     79             return 1;
     80         case INVALIDATE_BY_CLOSING_WITH_SHUTDOWN:
     81         case INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN:
     82         case INVALIDATE_BY_PURGING_WITH_SHUTDOWN:
     83             /* All keys must have been closed. */
     84             PSA_SESSION_DONE();
     85             break;
     86         case INVALIDATE_BY_SHUTDOWN:
     87             /* Some keys may remain behind, and we're testing that this
     88              * properly closes them. */
     89             mbedtls_psa_crypto_free();
     90             break;
     91     }
     92 
     93     PSA_ASSERT(psa_crypto_init());
     94     ASSERT_PSA_PRISTINE();
     95     return 1;
     96 
     97 exit:
     98     return 0;
     99 }
    100 
    101 #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC)
    102 #if defined(MBEDTLS_TEST_HOOKS)
    103 /* Artificially restrictable dynamic key store */
    104 #define KEY_SLICE_1_LENGTH 4
    105 #define KEY_SLICE_2_LENGTH 10
    106 static size_t tiny_key_slice_length(size_t slice_idx)
    107 {
    108     switch (slice_idx) {
    109         case 1: return KEY_SLICE_1_LENGTH;
    110         case 2: return KEY_SLICE_2_LENGTH;
    111         default: return 1;
    112     }
    113 }
    114 #define MAX_VOLATILE_KEYS                       \
    115     (KEY_SLICE_1_LENGTH + KEY_SLICE_2_LENGTH +  \
    116      psa_key_slot_volatile_slice_count() - 2)
    117 
    118 #else  /* Effectively unbounded dynamic key store */
    119 #undef MAX_VOLATILE_KEYS
    120 #endif
    121 
    122 #else  /* Static key store */
    123 #define MAX_VOLATILE_KEYS MBEDTLS_PSA_KEY_SLOT_COUNT
    124 #endif
    125 
    126 /* END_HEADER */
    127 
    128 /* BEGIN_DEPENDENCIES
    129  * depends_on:MBEDTLS_PSA_CRYPTO_C
    130  * END_DEPENDENCIES
    131  */
    132 
    133 /* BEGIN_CASE */
    134 void transient_slot_lifecycle(int owner_id_arg,
    135                               int usage_arg, int alg_arg,
    136                               int type_arg, data_t *key_data,
    137                               int invalidate_method_arg)
    138 {
    139     psa_algorithm_t alg = alg_arg;
    140     psa_key_usage_t usage_flags = usage_arg;
    141     psa_key_type_t type = type_arg;
    142     invalidate_method_t invalidate_method = invalidate_method_arg;
    143     mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
    144     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    145 
    146     mbedtls_test_set_step(1);
    147     PSA_ASSERT(psa_crypto_init());
    148 
    149     /* Import a key. */
    150 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
    151     mbedtls_key_owner_id_t owner_id = owner_id_arg;
    152 
    153     mbedtls_set_key_owner_id(&attributes, owner_id);
    154 #else
    155     (void) owner_id_arg;
    156 #endif
    157 
    158     psa_set_key_usage_flags(&attributes, usage_flags);
    159     psa_set_key_algorithm(&attributes, alg);
    160     psa_set_key_type(&attributes, type);
    161     PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
    162                               &key));
    163     TEST_ASSERT(!mbedtls_svc_key_id_is_null(key));
    164     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    165     TEST_EQUAL(psa_get_key_type(&attributes), type);
    166     psa_reset_key_attributes(&attributes);
    167 
    168 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
    169     {
    170         mbedtls_svc_key_id_t key_with_invalid_owner =
    171             mbedtls_svc_key_id_make(owner_id + 1,
    172                                     MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key));
    173 
    174         TEST_ASSERT(mbedtls_key_owner_id_equal(
    175                         owner_id,
    176                         MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key)));
    177         TEST_EQUAL(psa_get_key_attributes(key_with_invalid_owner, &attributes),
    178                    PSA_ERROR_INVALID_HANDLE);
    179     }
    180 #endif
    181 
    182     /*
    183      * Purge the key and make sure that it is still valid, as purging a
    184      * volatile key shouldn't invalidate/destroy it.
    185      */
    186     PSA_ASSERT(psa_purge_key(key));
    187     PSA_ASSERT(psa_get_key_attributes(key, &attributes));
    188     TEST_EQUAL(psa_get_key_type(&attributes), type);
    189     psa_reset_key_attributes(&attributes);
    190 
    191     /* Do something that invalidates the key. */
    192     mbedtls_test_set_step(2);
    193     if (!invalidate_key(invalidate_method, key)) {
    194         goto exit;
    195     }
    196     if (!invalidate_psa(invalidate_method)) {
    197         goto exit;
    198     }
    199 
    200     /* Test that the key is now invalid. */
    201     TEST_EQUAL(psa_get_key_attributes(key, &attributes),
    202                PSA_ERROR_INVALID_HANDLE);
    203     TEST_EQUAL(psa_close_key(key), PSA_ERROR_INVALID_HANDLE);
    204 
    205 exit:
    206     /*
    207      * Key attributes may have been returned by psa_get_key_attributes()
    208      * thus reset them as required.
    209      */
    210     psa_reset_key_attributes(&attributes);
    211 
    212     PSA_DONE();
    213 }
    214 /* END_CASE */
    215 
    216 /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
    217 void persistent_slot_lifecycle(int lifetime_arg, int owner_id_arg, int id_arg,
    218                                int usage_arg, int alg_arg, int alg2_arg,
    219                                int type_arg, data_t *key_data,
    220                                int invalidate_method_arg)
    221 {
    222     psa_key_lifetime_t lifetime = lifetime_arg;
    223     mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(owner_id_arg, id_arg);
    224     psa_algorithm_t alg = alg_arg;
    225     psa_algorithm_t alg2 = alg2_arg;
    226     psa_key_usage_t usage_flags = usage_arg;
    227     psa_key_type_t type = type_arg;
    228     invalidate_method_t invalidate_method = invalidate_method_arg;
    229     mbedtls_svc_key_id_t returned_id = MBEDTLS_SVC_KEY_ID_INIT;
    230     psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
    231     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    232     psa_key_attributes_t read_attributes = PSA_KEY_ATTRIBUTES_INIT;
    233     uint8_t *reexported = NULL;
    234     size_t reexported_length = -1;
    235 
    236 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
    237     mbedtls_svc_key_id_t wrong_owner_id =
    238         mbedtls_svc_key_id_make(owner_id_arg + 1, id_arg);
    239     mbedtls_svc_key_id_t invalid_svc_key_id = MBEDTLS_SVC_KEY_ID_INIT;
    240 #endif
    241 
    242     TEST_USES_KEY_ID(id);
    243 
    244     mbedtls_test_set_step(1);
    245     PSA_ASSERT(psa_crypto_init());
    246 
    247     psa_set_key_id(&attributes, id);
    248     psa_set_key_lifetime(&attributes, lifetime);
    249     psa_set_key_type(&attributes, type);
    250     psa_set_key_usage_flags(&attributes, usage_flags);
    251     psa_set_key_algorithm(&attributes, alg);
    252     psa_set_key_enrollment_algorithm(&attributes, alg2);
    253     PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
    254                               &returned_id));
    255     TEST_ASSERT(mbedtls_svc_key_id_equal(id, returned_id));
    256 
    257 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
    258     TEST_EQUAL(psa_open_key(wrong_owner_id, &invalid_svc_key_id),
    259                PSA_ERROR_DOES_NOT_EXIST);
    260 #endif
    261 
    262     PSA_ASSERT(psa_get_key_attributes(id, &attributes));
    263     TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
    264     TEST_ASSERT(mbedtls_svc_key_id_equal(
    265                     psa_get_key_id(&attributes), id));
    266     TEST_EQUAL(psa_get_key_usage_flags(&attributes),
    267                mbedtls_test_update_key_usage_flags(usage_flags));
    268     TEST_EQUAL(psa_get_key_algorithm(&attributes), alg);
    269     TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), alg2);
    270     TEST_EQUAL(psa_get_key_type(&attributes), type);
    271 
    272     /* Close the key and then open it. */
    273     PSA_ASSERT(psa_close_key(id));
    274 
    275 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
    276     TEST_EQUAL(psa_open_key(wrong_owner_id, &invalid_svc_key_id),
    277                PSA_ERROR_DOES_NOT_EXIST);
    278 #endif
    279 
    280     PSA_ASSERT(psa_open_key(id, &handle));
    281     TEST_ASSERT(!psa_key_handle_is_null(handle));
    282     PSA_ASSERT(psa_get_key_attributes(handle, &attributes));
    283     TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
    284     TEST_ASSERT(mbedtls_svc_key_id_equal(
    285                     psa_get_key_id(&attributes), id));
    286     TEST_EQUAL(psa_get_key_usage_flags(&attributes),
    287                mbedtls_test_update_key_usage_flags(usage_flags));
    288     TEST_EQUAL(psa_get_key_algorithm(&attributes), alg);
    289     TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), alg2);
    290     TEST_EQUAL(psa_get_key_type(&attributes), type);
    291 
    292     /*
    293      * Do something that wipes key data in volatile memory or destroy the
    294      * key.
    295      */
    296     mbedtls_test_set_step(2);
    297     if (!invalidate_key(invalidate_method, id)) {
    298         goto exit;
    299     }
    300     if (!invalidate_psa(invalidate_method)) {
    301         goto exit;
    302     }
    303 
    304     /* Try to reaccess the key. If we destroyed it, check that it doesn't
    305      * exist. Otherwise check that it still exists and has the expected
    306      * content. */
    307     switch (invalidate_method) {
    308         case INVALIDATE_BY_CLOSING:
    309         case INVALIDATE_BY_CLOSING_WITH_SHUTDOWN:
    310         case INVALIDATE_BY_PURGING:
    311         case INVALIDATE_BY_PURGING_WITH_SHUTDOWN:
    312         case INVALIDATE_BY_SHUTDOWN:
    313             PSA_ASSERT(psa_open_key(id, &handle));
    314             PSA_ASSERT(psa_get_key_attributes(id, &read_attributes));
    315             TEST_EQUAL(psa_get_key_lifetime(&attributes),
    316                        psa_get_key_lifetime(&read_attributes));
    317             TEST_ASSERT(mbedtls_svc_key_id_equal(
    318                             psa_get_key_id(&attributes),
    319                             psa_get_key_id(&read_attributes)));
    320             TEST_EQUAL(psa_get_key_usage_flags(&attributes),
    321                        mbedtls_test_update_key_usage_flags(usage_flags));
    322             TEST_EQUAL(psa_get_key_algorithm(&attributes),
    323                        psa_get_key_algorithm(&read_attributes));
    324             TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes),
    325                        psa_get_key_enrollment_algorithm(&read_attributes));
    326             TEST_EQUAL(psa_get_key_type(&attributes),
    327                        psa_get_key_type(&read_attributes));
    328             TEST_EQUAL(psa_get_key_bits(&attributes),
    329                        psa_get_key_bits(&read_attributes));
    330             TEST_CALLOC(reexported, key_data->len);
    331             if (usage_flags & PSA_KEY_USAGE_EXPORT) {
    332                 PSA_ASSERT(psa_export_key(id, reexported, key_data->len,
    333                                           &reexported_length));
    334                 TEST_MEMORY_COMPARE(key_data->x, key_data->len,
    335                                     reexported, reexported_length);
    336             } else {
    337                 TEST_EQUAL(psa_export_key(id, reexported,
    338                                           key_data->len, &reexported_length),
    339                            PSA_ERROR_NOT_PERMITTED);
    340             }
    341             PSA_ASSERT(psa_close_key(handle));
    342             break;
    343 
    344         case INVALIDATE_BY_DESTROYING:
    345         case INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN:
    346             /*
    347              * Test that the key handle and identifier are now not referring to an
    348              * existing key.
    349              */
    350             TEST_EQUAL(psa_get_key_attributes(handle, &read_attributes),
    351                        PSA_ERROR_INVALID_HANDLE);
    352             TEST_EQUAL(psa_close_key(handle), PSA_ERROR_INVALID_HANDLE);
    353             TEST_EQUAL(psa_get_key_attributes(id, &read_attributes),
    354                        PSA_ERROR_INVALID_HANDLE);
    355             break;
    356     }
    357 
    358 exit:
    359     /*
    360      * Key attributes may have been returned by psa_get_key_attributes()
    361      * thus reset them as required.
    362      */
    363     psa_reset_key_attributes(&attributes);
    364     psa_reset_key_attributes(&read_attributes);
    365 
    366     PSA_DONE();
    367     mbedtls_free(reexported);
    368 }
    369 /* END_CASE */
    370 
    371 /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
    372 void create_existent(int lifetime_arg, int owner_id_arg, int id_arg,
    373                      int reopen_policy_arg)
    374 {
    375     psa_key_lifetime_t lifetime = lifetime_arg;
    376     mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(owner_id_arg, id_arg);
    377     mbedtls_svc_key_id_t returned_id = MBEDTLS_SVC_KEY_ID_INIT;
    378     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    379     psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA;
    380     /* We need to tell the compiler that we meant to leave out the null character. */
    381     const uint8_t material1[5] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "a key";
    382     const uint8_t material2[5] MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING = "b key";
    383     size_t bits1 = PSA_BYTES_TO_BITS(sizeof(material1));
    384     uint8_t reexported[sizeof(material1)];
    385     size_t reexported_length;
    386     reopen_policy_t reopen_policy = reopen_policy_arg;
    387 
    388     TEST_USES_KEY_ID(id);
    389 
    390     PSA_ASSERT(psa_crypto_init());
    391 
    392     /* Create a key. */
    393     psa_set_key_id(&attributes, id);
    394     psa_set_key_lifetime(&attributes, lifetime);
    395     psa_set_key_type(&attributes, type1);
    396     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    397     psa_set_key_algorithm(&attributes, 0);
    398     PSA_ASSERT(psa_import_key(&attributes, material1, sizeof(material1),
    399                               &returned_id));
    400     TEST_ASSERT(mbedtls_svc_key_id_equal(id, returned_id));
    401 
    402     if (reopen_policy == CLOSE_BEFORE) {
    403         PSA_ASSERT(psa_close_key(id));
    404     }
    405 
    406     /* Attempt to create a new key in the same slot. */
    407     TEST_EQUAL(psa_import_key(&attributes, material2, sizeof(material2),
    408                               &returned_id),
    409                PSA_ERROR_ALREADY_EXISTS);
    410     TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_id));
    411 
    412     if (reopen_policy == CLOSE_AFTER) {
    413         PSA_ASSERT(psa_close_key(id));
    414     }
    415 
    416     /* Check that the original key hasn't changed. */
    417     psa_reset_key_attributes(&attributes);
    418     PSA_ASSERT(psa_get_key_attributes(id, &attributes));
    419     TEST_ASSERT(mbedtls_svc_key_id_equal(
    420                     psa_get_key_id(&attributes), id));
    421     TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
    422     TEST_EQUAL(psa_get_key_type(&attributes), type1);
    423     TEST_EQUAL(psa_get_key_bits(&attributes), bits1);
    424     TEST_EQUAL(psa_get_key_usage_flags(&attributes), PSA_KEY_USAGE_EXPORT);
    425     TEST_EQUAL(psa_get_key_algorithm(&attributes), 0);
    426 
    427     PSA_ASSERT(psa_export_key(id,
    428                               reexported, sizeof(reexported),
    429                               &reexported_length));
    430     TEST_MEMORY_COMPARE(material1, sizeof(material1),
    431                         reexported, reexported_length);
    432 
    433     PSA_ASSERT(psa_close_key(id));
    434 
    435 exit:
    436     /*
    437      * Key attributes may have been returned by psa_get_key_attributes()
    438      * thus reset them as required.
    439      */
    440     psa_reset_key_attributes(&attributes);
    441 
    442     PSA_DONE();
    443 }
    444 /* END_CASE */
    445 
    446 /* BEGIN_CASE */
    447 void open_fail(int id_arg,
    448                int expected_status_arg)
    449 {
    450     mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
    451     psa_status_t expected_status = expected_status_arg;
    452     psa_key_handle_t handle = mbedtls_svc_key_id_make(0xdead, 0xdead);
    453 
    454     PSA_ASSERT(psa_crypto_init());
    455 
    456     TEST_EQUAL(psa_open_key(id, &handle), expected_status);
    457     TEST_ASSERT(psa_key_handle_is_null(handle));
    458 
    459 exit:
    460     PSA_DONE();
    461 }
    462 /* END_CASE */
    463 
    464 /* BEGIN_CASE */
    465 void create_fail(int lifetime_arg, int id_arg,
    466                  int expected_status_arg)
    467 {
    468     psa_key_lifetime_t lifetime = lifetime_arg;
    469     mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
    470     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    471     psa_status_t expected_status = expected_status_arg;
    472     mbedtls_svc_key_id_t returned_id =
    473         mbedtls_svc_key_id_make(0xdead, 0xdead);
    474     uint8_t material[1] = { 'k' };
    475 
    476     TEST_USES_KEY_ID(id);
    477 
    478     PSA_ASSERT(psa_crypto_init());
    479 
    480     psa_set_key_lifetime(&attributes, lifetime);
    481     if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
    482         /*
    483          * Not possible to set a key identifier different from 0 through
    484          * PSA key attributes APIs thus accessing to the attributes
    485          * directly.
    486          */
    487         attributes.id = id;
    488     } else {
    489         psa_set_key_id(&attributes, id);
    490     }
    491 
    492     psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    493     TEST_EQUAL(psa_import_key(&attributes, material, sizeof(material),
    494                               &returned_id),
    495                expected_status);
    496     TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_id));
    497 
    498 exit:
    499     PSA_DONE();
    500 }
    501 /* END_CASE */
    502 
    503 /* BEGIN_CASE */
    504 void copy_across_lifetimes(int source_lifetime_arg, int source_owner_id_arg,
    505                            int source_id_arg, int source_usage_arg,
    506                            int source_alg_arg, int source_alg2_arg,
    507                            int type_arg, data_t *material,
    508                            int target_lifetime_arg, int target_owner_id_arg,
    509                            int target_id_arg, int target_usage_arg,
    510                            int target_alg_arg, int target_alg2_arg,
    511                            int expected_usage_arg,
    512                            int expected_alg_arg, int expected_alg2_arg)
    513 {
    514     psa_key_lifetime_t source_lifetime = source_lifetime_arg;
    515     mbedtls_svc_key_id_t source_id =
    516         mbedtls_svc_key_id_make(source_owner_id_arg, source_id_arg);
    517     psa_key_usage_t source_usage = source_usage_arg;
    518     psa_algorithm_t source_alg = source_alg_arg;
    519     psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
    520     psa_key_type_t source_type = type_arg;
    521     mbedtls_svc_key_id_t returned_source_id = MBEDTLS_SVC_KEY_ID_INIT;
    522     psa_key_lifetime_t target_lifetime = target_lifetime_arg;
    523     mbedtls_svc_key_id_t target_id =
    524         mbedtls_svc_key_id_make(target_owner_id_arg, target_id_arg);
    525     psa_key_usage_t target_usage = target_usage_arg;
    526     psa_algorithm_t target_alg = target_alg_arg;
    527     psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
    528     mbedtls_svc_key_id_t returned_target_id = MBEDTLS_SVC_KEY_ID_INIT;
    529     psa_key_handle_t target_handle = PSA_KEY_HANDLE_INIT;
    530     psa_key_usage_t expected_usage = expected_usage_arg;
    531     psa_algorithm_t expected_alg = expected_alg_arg;
    532     psa_algorithm_t expected_alg2 = expected_alg2_arg;
    533     uint8_t *export_buffer = NULL;
    534 
    535     TEST_USES_KEY_ID(source_id);
    536     TEST_USES_KEY_ID(target_id);
    537 
    538     PSA_ASSERT(psa_crypto_init());
    539 
    540     /* Populate the source slot. */
    541     psa_set_key_id(&source_attributes, source_id);
    542     psa_set_key_lifetime(&source_attributes, source_lifetime);
    543 
    544     psa_set_key_type(&source_attributes, source_type);
    545     psa_set_key_usage_flags(&source_attributes, source_usage);
    546     psa_set_key_algorithm(&source_attributes, source_alg);
    547     psa_set_key_enrollment_algorithm(&source_attributes, source_alg2_arg);
    548     PSA_ASSERT(psa_import_key(&source_attributes,
    549                               material->x, material->len,
    550                               &returned_source_id));
    551     /* Update the attributes with the bit size. */
    552     PSA_ASSERT(psa_get_key_attributes(returned_source_id,
    553                                       &source_attributes));
    554 
    555     /* Prepare the target slot. */
    556     psa_set_key_id(&target_attributes, target_id);
    557     psa_set_key_lifetime(&target_attributes, target_lifetime);
    558 
    559     psa_set_key_usage_flags(&target_attributes, target_usage);
    560     psa_set_key_algorithm(&target_attributes, target_alg);
    561     psa_set_key_enrollment_algorithm(&target_attributes, target_alg2_arg);
    562 
    563     /* Copy the key. */
    564     PSA_ASSERT(psa_copy_key(returned_source_id,
    565                             &target_attributes, &returned_target_id));
    566 
    567     /* Destroy the source to ensure that this doesn't affect the target. */
    568     PSA_ASSERT(psa_destroy_key(returned_source_id));
    569 
    570     /* If the target key is persistent, restart the system to make
    571      * sure that the material is still alive. */
    572     if (!PSA_KEY_LIFETIME_IS_VOLATILE(target_lifetime)) {
    573         mbedtls_psa_crypto_free();
    574         PSA_ASSERT(psa_crypto_init());
    575         PSA_ASSERT(psa_open_key(target_id, &target_handle));
    576     }
    577 
    578     /* Test that the target slot has the expected content. */
    579     psa_reset_key_attributes(&target_attributes);
    580     PSA_ASSERT(psa_get_key_attributes(returned_target_id,
    581                                       &target_attributes));
    582 
    583     if (!PSA_KEY_LIFETIME_IS_VOLATILE(target_lifetime)) {
    584         TEST_ASSERT(mbedtls_svc_key_id_equal(
    585                         target_id, psa_get_key_id(&target_attributes)));
    586     } else {
    587 #if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
    588         TEST_EQUAL(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(returned_target_id),
    589                    target_owner_id_arg);
    590 #endif
    591     }
    592 
    593     TEST_EQUAL(target_lifetime, psa_get_key_lifetime(&target_attributes));
    594     TEST_EQUAL(source_type, psa_get_key_type(&target_attributes));
    595     TEST_EQUAL(psa_get_key_bits(&source_attributes),
    596                psa_get_key_bits(&target_attributes));
    597     TEST_EQUAL(expected_usage, psa_get_key_usage_flags(&target_attributes));
    598     TEST_EQUAL(expected_alg, psa_get_key_algorithm(&target_attributes));
    599     TEST_EQUAL(expected_alg2,
    600                psa_get_key_enrollment_algorithm(&target_attributes));
    601     if (expected_usage & PSA_KEY_USAGE_EXPORT) {
    602         size_t length;
    603         TEST_CALLOC(export_buffer, material->len);
    604         PSA_ASSERT(psa_export_key(returned_target_id, export_buffer,
    605                                   material->len, &length));
    606         TEST_MEMORY_COMPARE(material->x, material->len,
    607                             export_buffer, length);
    608     } else {
    609         size_t length;
    610         /* Check that the key is actually non-exportable. */
    611         TEST_EQUAL(psa_export_key(returned_target_id, export_buffer,
    612                                   material->len, &length),
    613                    PSA_ERROR_NOT_PERMITTED);
    614     }
    615 
    616     PSA_ASSERT(psa_destroy_key(returned_target_id));
    617 
    618 exit:
    619     /*
    620      * Source and target key attributes may have been returned by
    621      * psa_get_key_attributes() thus reset them as required.
    622      */
    623     psa_reset_key_attributes(&source_attributes);
    624     psa_reset_key_attributes(&target_attributes);
    625 
    626     PSA_DONE();
    627     mbedtls_free(export_buffer);
    628 }
    629 /* END_CASE */
    630 
    631 /* BEGIN_CASE */
    632 void copy_to_occupied(int source_lifetime_arg, int source_id_arg,
    633                       int source_usage_arg, int source_alg_arg,
    634                       int source_type_arg, data_t *source_material,
    635                       int target_lifetime_arg, int target_id_arg,
    636                       int target_usage_arg, int target_alg_arg,
    637                       int target_type_arg, data_t *target_material)
    638 {
    639     psa_key_lifetime_t source_lifetime = source_lifetime_arg;
    640     mbedtls_svc_key_id_t source_id =
    641         mbedtls_svc_key_id_make(1, source_id_arg);
    642     psa_key_usage_t source_usage = source_usage_arg;
    643     psa_algorithm_t source_alg = source_alg_arg;
    644     psa_key_type_t source_type = source_type_arg;
    645     mbedtls_svc_key_id_t returned_source_id = MBEDTLS_SVC_KEY_ID_INIT;
    646     psa_key_lifetime_t target_lifetime = target_lifetime_arg;
    647     mbedtls_svc_key_id_t target_id =
    648         mbedtls_svc_key_id_make(1, target_id_arg);
    649     psa_key_usage_t target_usage = target_usage_arg;
    650     psa_algorithm_t target_alg = target_alg_arg;
    651     psa_key_type_t target_type = target_type_arg;
    652     mbedtls_svc_key_id_t returned_target_id = MBEDTLS_SVC_KEY_ID_INIT;
    653     mbedtls_svc_key_id_t new_key = MBEDTLS_SVC_KEY_ID_INIT;
    654     uint8_t *export_buffer = NULL;
    655     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    656     psa_key_attributes_t attributes1 = PSA_KEY_ATTRIBUTES_INIT;
    657     psa_key_attributes_t attributes2 = PSA_KEY_ATTRIBUTES_INIT;
    658 
    659     TEST_USES_KEY_ID(source_id);
    660     TEST_USES_KEY_ID(target_id);
    661 
    662     PSA_ASSERT(psa_crypto_init());
    663 
    664     /* Populate the source slot. */
    665     if (!PSA_KEY_LIFETIME_IS_VOLATILE(source_lifetime)) {
    666         psa_set_key_id(&attributes, source_id);
    667         psa_set_key_lifetime(&attributes, source_lifetime);
    668     }
    669     psa_set_key_type(&attributes, source_type);
    670     psa_set_key_usage_flags(&attributes, source_usage);
    671     psa_set_key_algorithm(&attributes, source_alg);
    672     PSA_ASSERT(psa_import_key(&attributes,
    673                               source_material->x, source_material->len,
    674                               &returned_source_id));
    675 
    676     /* Populate the target slot. */
    677     if (mbedtls_svc_key_id_equal(target_id, source_id)) {
    678         returned_target_id = returned_source_id;
    679     } else {
    680         psa_set_key_id(&attributes1, target_id);
    681         psa_set_key_lifetime(&attributes1, target_lifetime);
    682         psa_set_key_type(&attributes1, target_type);
    683         psa_set_key_usage_flags(&attributes1, target_usage);
    684         psa_set_key_algorithm(&attributes1, target_alg);
    685         PSA_ASSERT(psa_import_key(&attributes1,
    686                                   target_material->x, target_material->len,
    687                                   &returned_target_id));
    688     }
    689 
    690     PSA_ASSERT(psa_get_key_attributes(returned_target_id, &attributes1));
    691 
    692     /* Make a copy attempt. */
    693     psa_set_key_id(&attributes, target_id);
    694     psa_set_key_lifetime(&attributes, target_lifetime);
    695     TEST_EQUAL(psa_copy_key(returned_source_id,
    696                             &attributes, &new_key),
    697                PSA_ERROR_ALREADY_EXISTS);
    698     TEST_ASSERT(mbedtls_svc_key_id_is_null(new_key));
    699 
    700     /* Test that the target slot is unaffected. */
    701     PSA_ASSERT(psa_get_key_attributes(returned_target_id, &attributes2));
    702     TEST_ASSERT(mbedtls_svc_key_id_equal(
    703                     psa_get_key_id(&attributes1),
    704                     psa_get_key_id(&attributes2)));
    705     TEST_EQUAL(psa_get_key_lifetime(&attributes1),
    706                psa_get_key_lifetime(&attributes2));
    707     TEST_EQUAL(psa_get_key_type(&attributes1),
    708                psa_get_key_type(&attributes2));
    709     TEST_EQUAL(psa_get_key_bits(&attributes1),
    710                psa_get_key_bits(&attributes2));
    711     TEST_EQUAL(psa_get_key_usage_flags(&attributes1),
    712                psa_get_key_usage_flags(&attributes2));
    713     TEST_EQUAL(psa_get_key_algorithm(&attributes1),
    714                psa_get_key_algorithm(&attributes2));
    715     if (target_usage & PSA_KEY_USAGE_EXPORT) {
    716         size_t length;
    717         TEST_CALLOC(export_buffer, target_material->len);
    718         PSA_ASSERT(psa_export_key(returned_target_id, export_buffer,
    719                                   target_material->len, &length));
    720         TEST_MEMORY_COMPARE(target_material->x, target_material->len,
    721                             export_buffer, length);
    722     }
    723 
    724     PSA_ASSERT(psa_destroy_key(returned_source_id));
    725     if (!mbedtls_svc_key_id_equal(target_id, source_id)) {
    726         PSA_ASSERT(psa_destroy_key(returned_target_id));
    727     }
    728 
    729 exit:
    730     /*
    731      * Key attributes may have been returned by psa_get_key_attributes()
    732      * thus reset them as required.
    733      */
    734     psa_reset_key_attributes(&attributes1);
    735     psa_reset_key_attributes(&attributes2);
    736 
    737     PSA_DONE();
    738     mbedtls_free(export_buffer);
    739 }
    740 /* END_CASE */
    741 
    742 /* BEGIN_CASE */
    743 void invalid_handle(int handle_construction,
    744                     int close_status_arg)
    745 {
    746     psa_key_handle_t valid_handle = PSA_KEY_HANDLE_INIT;
    747     psa_key_handle_t invalid_handle = PSA_KEY_HANDLE_INIT;
    748     psa_key_id_t key_id;
    749     psa_status_t close_status = close_status_arg;
    750     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    751     uint8_t material[1] = { 'a' };
    752 
    753     PSA_ASSERT(psa_crypto_init());
    754 
    755     /* Allocate a handle and store a key in it. */
    756     psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    757     psa_set_key_usage_flags(&attributes, 0);
    758     psa_set_key_algorithm(&attributes, 0);
    759     PSA_ASSERT(psa_import_key(&attributes,
    760                               material, sizeof(material),
    761                               &valid_handle));
    762     TEST_ASSERT(!psa_key_handle_is_null(valid_handle));
    763 
    764     /* Construct an invalid handle as specified in the test case data. */
    765     switch (handle_construction) {
    766         case INVALID_HANDLE_0:
    767             invalid_handle = PSA_KEY_HANDLE_INIT;
    768             break;
    769         case INVALID_HANDLE_UNOPENED:
    770 
    771             /*
    772              * MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile
    773              * key identifier as the imported key is a volatile key. Volatile
    774              * key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN
    775              * to PSA_KEY_ID_VOLATILE_MAX included. It is very unlikely that
    776              * all IDs are used up to the last one, so pick
    777              * PSA_KEY_ID_VOLATILE_MAX to build an unopened and thus invalid
    778              * identifier.
    779              */
    780             key_id = PSA_KEY_ID_VOLATILE_MAX;
    781 
    782             invalid_handle =
    783                 mbedtls_svc_key_id_make(0, key_id);
    784             break;
    785         case INVALID_HANDLE_CLOSED:
    786             PSA_ASSERT(psa_import_key(&attributes,
    787                                       material, sizeof(material),
    788                                       &invalid_handle));
    789             PSA_ASSERT(psa_destroy_key(invalid_handle));
    790             break;
    791         case INVALID_HANDLE_HUGE:
    792             invalid_handle =
    793                 mbedtls_svc_key_id_make(0, PSA_KEY_ID_VENDOR_MAX + 1);
    794             break;
    795         default:
    796             TEST_FAIL("unknown handle construction");
    797     }
    798 
    799     /* Attempt to use the invalid handle. */
    800     TEST_EQUAL(psa_get_key_attributes(invalid_handle, &attributes),
    801                PSA_ERROR_INVALID_HANDLE);
    802     TEST_EQUAL(psa_close_key(invalid_handle), close_status);
    803     TEST_EQUAL(psa_destroy_key(invalid_handle), close_status);
    804 
    805     /* After all this, check that the original handle is intact. */
    806     PSA_ASSERT(psa_get_key_attributes(valid_handle, &attributes));
    807     TEST_EQUAL(psa_get_key_type(&attributes), PSA_KEY_TYPE_RAW_DATA);
    808     TEST_EQUAL(psa_get_key_bits(&attributes),
    809                PSA_BYTES_TO_BITS(sizeof(material)));
    810     PSA_ASSERT(psa_close_key(valid_handle));
    811 
    812 exit:
    813     /*
    814      * Key attributes may have been returned by psa_get_key_attributes()
    815      * thus reset them as required.
    816      */
    817     psa_reset_key_attributes(&attributes);
    818 
    819     PSA_DONE();
    820 }
    821 /* END_CASE */
    822 
    823 /* BEGIN_CASE */
    824 void many_transient_keys(int max_keys_arg)
    825 {
    826     mbedtls_svc_key_id_t *keys = NULL;
    827     size_t max_keys = max_keys_arg;
    828     size_t i, j;
    829     psa_status_t status;
    830     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    831     uint8_t exported[sizeof(size_t)];
    832     size_t exported_length;
    833 
    834     TEST_CALLOC(keys, max_keys);
    835     PSA_ASSERT(psa_crypto_init());
    836 
    837     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    838     psa_set_key_algorithm(&attributes, 0);
    839     psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    840 
    841     for (i = 0; i < max_keys; i++) {
    842         mbedtls_test_set_step(i);
    843         status = psa_import_key(&attributes,
    844                                 (uint8_t *) &i, sizeof(i),
    845                                 &keys[i]);
    846         PSA_ASSERT(status);
    847         TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i]));
    848         for (j = 0; j < i; j++) {
    849             TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j]));
    850         }
    851     }
    852 
    853     for (i = 1; i < max_keys; i++) {
    854         mbedtls_test_set_step(i);
    855         PSA_ASSERT(psa_close_key(keys[i - 1]));
    856         PSA_ASSERT(psa_export_key(keys[i],
    857                                   exported, sizeof(exported),
    858                                   &exported_length));
    859         TEST_MEMORY_COMPARE(exported, exported_length,
    860                             (uint8_t *) &i, sizeof(i));
    861     }
    862     PSA_ASSERT(psa_close_key(keys[i - 1]));
    863 
    864 exit:
    865     PSA_DONE();
    866     mbedtls_free(keys);
    867 }
    868 /* END_CASE */
    869 
    870 /* BEGIN_CASE depends_on:MAX_VOLATILE_KEYS */
    871 /*
    872  * 1. Fill the key store with volatile keys.
    873  * 2. Check that attempting to create another volatile key fails without
    874  *    corrupting the key store.
    875  * 3. Destroy the key specified by key_to_destroy. This is the number of the
    876  *    key in creation order (e.g. 0 means the first key that was created).
    877  *    It can also  be a negative value to count in reverse order (e.g.
    878  *    -1 means to destroy the last key that was created).
    879  * 4. Check that creating another volatile key succeeds.
    880  */
    881 void fill_key_store(int key_to_destroy_arg)
    882 {
    883     mbedtls_svc_key_id_t *keys = NULL;
    884     size_t max_keys = MAX_VOLATILE_KEYS;
    885     size_t i, j;
    886     psa_status_t status;
    887     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    888     uint8_t exported[sizeof(size_t)];
    889     size_t exported_length;
    890 
    891 #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
    892     mbedtls_test_hook_psa_volatile_key_slice_length = &tiny_key_slice_length;
    893 #endif
    894 
    895     PSA_ASSERT(psa_crypto_init());
    896 
    897     mbedtls_psa_stats_t stats;
    898     mbedtls_psa_get_stats(&stats);
    899     /* Account for any system-created volatile key, e.g. for the RNG. */
    900     max_keys -= stats.volatile_slots;
    901     TEST_CALLOC(keys, max_keys + 1);
    902 
    903     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    904     psa_set_key_algorithm(&attributes, 0);
    905     psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    906 
    907     /* Fill the key store. */
    908     for (i = 0; i < max_keys; i++) {
    909         mbedtls_test_set_step(i);
    910         status = psa_import_key(&attributes,
    911                                 (uint8_t *) &i, sizeof(i),
    912                                 &keys[i]);
    913         PSA_ASSERT(status);
    914         TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i]));
    915         for (j = 0; j < i; j++) {
    916             TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j]));
    917         }
    918     }
    919 
    920     /* Attempt to overfill. */
    921     mbedtls_test_set_step(max_keys);
    922     status = psa_import_key(&attributes,
    923                             (uint8_t *) &max_keys, sizeof(max_keys),
    924                             &keys[max_keys]);
    925     TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
    926     TEST_ASSERT(mbedtls_svc_key_id_is_null(keys[max_keys]));
    927 
    928     /* Check that the keys are not corrupted. */
    929     for (i = 0; i < max_keys; i++) {
    930         mbedtls_test_set_step(i);
    931         PSA_ASSERT(psa_export_key(keys[i],
    932                                   exported, sizeof(exported),
    933                                   &exported_length));
    934         TEST_MEMORY_COMPARE(exported, exported_length,
    935                             (uint8_t *) &i, sizeof(i));
    936     }
    937 
    938     /* Destroy one key and try again. */
    939     size_t key_to_destroy = (key_to_destroy_arg >= 0 ?
    940                              (size_t) key_to_destroy_arg :
    941                              max_keys + key_to_destroy_arg);
    942     mbedtls_svc_key_id_t reused_id = keys[key_to_destroy];
    943     const uint8_t replacement_value[1] = { 0x64 };
    944     PSA_ASSERT(psa_destroy_key(keys[key_to_destroy]));
    945     keys[key_to_destroy] = MBEDTLS_SVC_KEY_ID_INIT;
    946     status = psa_import_key(&attributes,
    947                             replacement_value, sizeof(replacement_value),
    948                             &keys[key_to_destroy]);
    949     PSA_ASSERT(status);
    950     /* Since the key store was full except for one key, the new key must be
    951      * in the same slot in the key store as the destroyed key.
    952      * Since volatile keys IDs are assigned based on which slot contains
    953      * the key, the new key should have the same ID as the destroyed key.
    954      */
    955     TEST_ASSERT(mbedtls_svc_key_id_equal(reused_id, keys[key_to_destroy]));
    956 
    957     /* Check that the keys are not corrupted and destroy them. */
    958     for (i = 0; i < max_keys; i++) {
    959         mbedtls_test_set_step(i);
    960         PSA_ASSERT(psa_export_key(keys[i],
    961                                   exported, sizeof(exported),
    962                                   &exported_length));
    963         if (i == key_to_destroy) {
    964             TEST_MEMORY_COMPARE(exported, exported_length,
    965                                 replacement_value, sizeof(replacement_value));
    966         } else {
    967             TEST_MEMORY_COMPARE(exported, exported_length,
    968                                 (uint8_t *) &i, sizeof(i));
    969         }
    970         PSA_ASSERT(psa_destroy_key(keys[i]));
    971         keys[i] = MBEDTLS_SVC_KEY_ID_INIT;
    972     }
    973 
    974 exit:
    975     PSA_DONE();
    976     mbedtls_free(keys);
    977 #if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
    978     mbedtls_test_hook_psa_volatile_key_slice_length = NULL;
    979 #endif
    980 }
    981 /* END_CASE */
    982 
    983 /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
    984 void key_slot_eviction_to_import_new_key(int lifetime_arg)
    985 {
    986     psa_key_lifetime_t lifetime = (psa_key_lifetime_t) lifetime_arg;
    987     size_t i;
    988     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    989     uint8_t exported[sizeof(size_t)];
    990     size_t exported_length;
    991     mbedtls_svc_key_id_t key, returned_key_id;
    992 
    993     PSA_ASSERT(psa_crypto_init());
    994 
    995     psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    996     psa_set_key_algorithm(&attributes, 0);
    997     psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    998 
    999     /*
   1000      * Create MBEDTLS_PSA_KEY_SLOT_COUNT persistent keys.
   1001      */
   1002     for (i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
   1003         key = mbedtls_svc_key_id_make(i, i + 1);
   1004         psa_set_key_id(&attributes, key);
   1005         PSA_ASSERT(psa_import_key(&attributes,
   1006                                   (uint8_t *) &i, sizeof(i),
   1007                                   &returned_key_id));
   1008         TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key));
   1009     }
   1010 
   1011     /*
   1012      * Create a new persistent or volatile key. When creating the key,
   1013      * one of the descriptions of the previously created persistent keys
   1014      * is removed from the RAM key slots. This makes room to store its
   1015      * description in RAM.
   1016      */
   1017     i = MBEDTLS_PSA_KEY_SLOT_COUNT;
   1018     key = mbedtls_svc_key_id_make(i, i + 1);
   1019     psa_set_key_id(&attributes, key);
   1020     psa_set_key_lifetime(&attributes, lifetime);
   1021 
   1022     PSA_ASSERT(psa_import_key(&attributes,
   1023                               (uint8_t *) &i, sizeof(i),
   1024                               &returned_key_id));
   1025     if (lifetime != PSA_KEY_LIFETIME_VOLATILE) {
   1026         TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key));
   1027     } else {
   1028         TEST_ASSERT(psa_key_id_is_volatile(
   1029                         MBEDTLS_SVC_KEY_ID_GET_KEY_ID(returned_key_id)));
   1030     }
   1031 
   1032     /*
   1033      * Check that we can export all ( MBEDTLS_PSA_KEY_SLOT_COUNT + 1 ) keys,
   1034      * that they have the expected value and destroy them. In that process,
   1035      * the description of the persistent key that was evicted from the RAM
   1036      * slots when creating the last key is restored in a RAM slot to export
   1037      * its value.
   1038      */
   1039     for (i = 0; i <= MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
   1040         if (i < MBEDTLS_PSA_KEY_SLOT_COUNT) {
   1041             key = mbedtls_svc_key_id_make(i, i + 1);
   1042         } else {
   1043             key = returned_key_id;
   1044         }
   1045 
   1046         PSA_ASSERT(psa_export_key(key,
   1047                                   exported, sizeof(exported),
   1048                                   &exported_length));
   1049         TEST_MEMORY_COMPARE(exported, exported_length,
   1050                             (uint8_t *) &i, sizeof(i));
   1051         PSA_ASSERT(psa_destroy_key(key));
   1052     }
   1053 
   1054 exit:
   1055     PSA_DONE();
   1056 }
   1057 /* END_CASE */
   1058 
   1059 /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C:!MBEDTLS_PSA_KEY_STORE_DYNAMIC */
   1060 void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
   1061 {
   1062     psa_status_t status;
   1063     size_t i;
   1064     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
   1065     uint8_t exported[sizeof(size_t)];
   1066     size_t exported_length;
   1067     mbedtls_svc_key_id_t persistent_key = MBEDTLS_SVC_KEY_ID_INIT;
   1068     mbedtls_svc_key_id_t persistent_key2 = MBEDTLS_SVC_KEY_ID_INIT;
   1069     mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
   1070     mbedtls_svc_key_id_t *keys = NULL;
   1071     mbedtls_psa_stats_t psa_key_slots_stats;
   1072     size_t available_key_slots = 0;
   1073 
   1074     TEST_ASSERT(MBEDTLS_PSA_KEY_SLOT_COUNT >= 1);
   1075 
   1076     PSA_ASSERT(psa_crypto_init());
   1077     mbedtls_psa_get_stats(&psa_key_slots_stats);
   1078     available_key_slots = psa_key_slots_stats.empty_slots;
   1079 
   1080     TEST_CALLOC(keys, available_key_slots);
   1081 
   1082     psa_set_key_usage_flags(&attributes,
   1083                             PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY);
   1084     psa_set_key_algorithm(&attributes, 0);
   1085     psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
   1086 
   1087     /*
   1088      * Create a persistent key
   1089      */
   1090     persistent_key = mbedtls_svc_key_id_make(0x100, 0x205);
   1091     psa_set_key_id(&attributes, persistent_key);
   1092     PSA_ASSERT(psa_import_key(&attributes,
   1093                               (uint8_t *) &persistent_key,
   1094                               sizeof(persistent_key),
   1095                               &returned_key_id));
   1096     TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, persistent_key));
   1097 
   1098     /*
   1099      * Create the maximum available number of keys that are locked in
   1100      * memory. This can be:
   1101      * - volatile keys, when MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled;
   1102      * - opened persistent keys (could work, but not currently implemented
   1103      *   in this test function);
   1104      * - keys in use by another thread (we don't do this because it would
   1105      *   be hard to arrange and we can't control how long the keys are
   1106      *   locked anyway).
   1107      */
   1108     psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
   1109     for (i = 0; i < available_key_slots; i++) {
   1110         PSA_ASSERT(psa_import_key(&attributes,
   1111                                   (uint8_t *) &i, sizeof(i),
   1112                                   &keys[i]));
   1113     }
   1114     psa_reset_key_attributes(&attributes);
   1115 
   1116     /*
   1117      * Check that we cannot access the persistent key as all slots are
   1118      * occupied by volatile keys and the implementation needs to load the
   1119      * persistent key description in a slot to be able to access it.
   1120      */
   1121     status = psa_get_key_attributes(persistent_key, &attributes);
   1122     TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
   1123 
   1124     /*
   1125      * Check we can export the volatile key created last and that it has the
   1126      * expected value. Then, destroy it.
   1127      */
   1128     PSA_ASSERT(psa_export_key(keys[available_key_slots - 1],
   1129                               exported, sizeof(exported),
   1130                               &exported_length));
   1131     i = available_key_slots - 1;
   1132     TEST_MEMORY_COMPARE(exported, exported_length, (uint8_t *) &i, sizeof(i));
   1133     PSA_ASSERT(psa_destroy_key(keys[available_key_slots - 1]));
   1134 
   1135     /*
   1136      * Check that we can now access the persistent key again.
   1137      */
   1138     PSA_ASSERT(psa_get_key_attributes(persistent_key, &attributes));
   1139     TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.id,
   1140                                          persistent_key));
   1141 
   1142     /*
   1143      * Check that we cannot copy the persistent key as all slots are occupied
   1144      * by the persistent key and the volatile keys and the slot containing the
   1145      * persistent key cannot be reclaimed as it contains the key to copy.
   1146      */
   1147     persistent_key2 = mbedtls_svc_key_id_make(0x100, 0x204);
   1148     psa_set_key_id(&attributes, persistent_key2);
   1149     status = psa_copy_key(persistent_key, &attributes, &returned_key_id);
   1150     TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
   1151 
   1152     /*
   1153      * Check we can export the remaining volatile keys and that they have the
   1154      * expected values.
   1155      */
   1156     for (i = 0; i < (available_key_slots - 1); i++) {
   1157         PSA_ASSERT(psa_export_key(keys[i],
   1158                                   exported, sizeof(exported),
   1159                                   &exported_length));
   1160         TEST_MEMORY_COMPARE(exported, exported_length,
   1161                             (uint8_t *) &i, sizeof(i));
   1162         PSA_ASSERT(psa_destroy_key(keys[i]));
   1163     }
   1164 
   1165     /*
   1166      * Check we can export the persistent key and that it have the expected
   1167      * value.
   1168      */
   1169 
   1170     PSA_ASSERT(psa_export_key(persistent_key, exported, sizeof(exported),
   1171                               &exported_length));
   1172     TEST_MEMORY_COMPARE(exported, exported_length,
   1173                         (uint8_t *) &persistent_key, sizeof(persistent_key));
   1174 exit:
   1175     /*
   1176      * Key attributes may have been returned by psa_get_key_attributes()
   1177      * thus reset them as required.
   1178      */
   1179     psa_reset_key_attributes(&attributes);
   1180 
   1181     psa_destroy_key(persistent_key);
   1182     PSA_DONE();
   1183     mbedtls_free(keys);
   1184 }
   1185 /* END_CASE */