1/* BEGIN_HEADER */
2#include <stdint.h>
3
4#include "psa_crypto_slot_management.h"
5#include "psa_crypto_storage.h"
6
7typedef 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
30typedef enum {
31    KEEP_OPEN,
32    CLOSE_BEFORE,
33    CLOSE_AFTER,
34} reopen_policy_t;
35
36typedef 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 */
46static 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;
68exit:
69    return 0;
70}
71
72/** Restart the PSA subsystem if \p invalidate_method says so. */
73static 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
97exit:
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
106static 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 */
134void 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
205exit:
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 */
217void 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
358exit:
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 */
372void 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    const uint8_t material1[5] = "a key";
381    const uint8_t material2[5] = "b key";
382    size_t bits1 = PSA_BYTES_TO_BITS(sizeof(material1));
383    uint8_t reexported[sizeof(material1)];
384    size_t reexported_length;
385    reopen_policy_t reopen_policy = reopen_policy_arg;
386
387    TEST_USES_KEY_ID(id);
388
389    PSA_ASSERT(psa_crypto_init());
390
391    /* Create a key. */
392    psa_set_key_id(&attributes, id);
393    psa_set_key_lifetime(&attributes, lifetime);
394    psa_set_key_type(&attributes, type1);
395    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
396    psa_set_key_algorithm(&attributes, 0);
397    PSA_ASSERT(psa_import_key(&attributes, material1, sizeof(material1),
398                              &returned_id));
399    TEST_ASSERT(mbedtls_svc_key_id_equal(id, returned_id));
400
401    if (reopen_policy == CLOSE_BEFORE) {
402        PSA_ASSERT(psa_close_key(id));
403    }
404
405    /* Attempt to create a new key in the same slot. */
406    TEST_EQUAL(psa_import_key(&attributes, material2, sizeof(material2),
407                              &returned_id),
408               PSA_ERROR_ALREADY_EXISTS);
409    TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_id));
410
411    if (reopen_policy == CLOSE_AFTER) {
412        PSA_ASSERT(psa_close_key(id));
413    }
414
415    /* Check that the original key hasn't changed. */
416    psa_reset_key_attributes(&attributes);
417    PSA_ASSERT(psa_get_key_attributes(id, &attributes));
418    TEST_ASSERT(mbedtls_svc_key_id_equal(
419                    psa_get_key_id(&attributes), id));
420    TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
421    TEST_EQUAL(psa_get_key_type(&attributes), type1);
422    TEST_EQUAL(psa_get_key_bits(&attributes), bits1);
423    TEST_EQUAL(psa_get_key_usage_flags(&attributes), PSA_KEY_USAGE_EXPORT);
424    TEST_EQUAL(psa_get_key_algorithm(&attributes), 0);
425
426    PSA_ASSERT(psa_export_key(id,
427                              reexported, sizeof(reexported),
428                              &reexported_length));
429    TEST_MEMORY_COMPARE(material1, sizeof(material1),
430                        reexported, reexported_length);
431
432    PSA_ASSERT(psa_close_key(id));
433
434exit:
435    /*
436     * Key attributes may have been returned by psa_get_key_attributes()
437     * thus reset them as required.
438     */
439    psa_reset_key_attributes(&attributes);
440
441    PSA_DONE();
442}
443/* END_CASE */
444
445/* BEGIN_CASE */
446void open_fail(int id_arg,
447               int expected_status_arg)
448{
449    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
450    psa_status_t expected_status = expected_status_arg;
451    psa_key_handle_t handle = mbedtls_svc_key_id_make(0xdead, 0xdead);
452
453    PSA_ASSERT(psa_crypto_init());
454
455    TEST_EQUAL(psa_open_key(id, &handle), expected_status);
456    TEST_ASSERT(psa_key_handle_is_null(handle));
457
458exit:
459    PSA_DONE();
460}
461/* END_CASE */
462
463/* BEGIN_CASE */
464void create_fail(int lifetime_arg, int id_arg,
465                 int expected_status_arg)
466{
467    psa_key_lifetime_t lifetime = lifetime_arg;
468    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
469    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
470    psa_status_t expected_status = expected_status_arg;
471    mbedtls_svc_key_id_t returned_id =
472        mbedtls_svc_key_id_make(0xdead, 0xdead);
473    uint8_t material[1] = { 'k' };
474
475    TEST_USES_KEY_ID(id);
476
477    PSA_ASSERT(psa_crypto_init());
478
479    psa_set_key_lifetime(&attributes, lifetime);
480    if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
481        /*
482         * Not possible to set a key identifier different from 0 through
483         * PSA key attributes APIs thus accessing to the attributes
484         * directly.
485         */
486        attributes.id = id;
487    } else {
488        psa_set_key_id(&attributes, id);
489    }
490
491    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
492    TEST_EQUAL(psa_import_key(&attributes, material, sizeof(material),
493                              &returned_id),
494               expected_status);
495    TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_id));
496
497exit:
498    PSA_DONE();
499}
500/* END_CASE */
501
502/* BEGIN_CASE */
503void copy_across_lifetimes(int source_lifetime_arg, int source_owner_id_arg,
504                           int source_id_arg, int source_usage_arg,
505                           int source_alg_arg, int source_alg2_arg,
506                           int type_arg, data_t *material,
507                           int target_lifetime_arg, int target_owner_id_arg,
508                           int target_id_arg, int target_usage_arg,
509                           int target_alg_arg, int target_alg2_arg,
510                           int expected_usage_arg,
511                           int expected_alg_arg, int expected_alg2_arg)
512{
513    psa_key_lifetime_t source_lifetime = source_lifetime_arg;
514    mbedtls_svc_key_id_t source_id =
515        mbedtls_svc_key_id_make(source_owner_id_arg, source_id_arg);
516    psa_key_usage_t source_usage = source_usage_arg;
517    psa_algorithm_t source_alg = source_alg_arg;
518    psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
519    psa_key_type_t source_type = type_arg;
520    mbedtls_svc_key_id_t returned_source_id = MBEDTLS_SVC_KEY_ID_INIT;
521    psa_key_lifetime_t target_lifetime = target_lifetime_arg;
522    mbedtls_svc_key_id_t target_id =
523        mbedtls_svc_key_id_make(target_owner_id_arg, target_id_arg);
524    psa_key_usage_t target_usage = target_usage_arg;
525    psa_algorithm_t target_alg = target_alg_arg;
526    psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
527    mbedtls_svc_key_id_t returned_target_id = MBEDTLS_SVC_KEY_ID_INIT;
528    psa_key_handle_t target_handle = PSA_KEY_HANDLE_INIT;
529    psa_key_usage_t expected_usage = expected_usage_arg;
530    psa_algorithm_t expected_alg = expected_alg_arg;
531    psa_algorithm_t expected_alg2 = expected_alg2_arg;
532    uint8_t *export_buffer = NULL;
533
534    TEST_USES_KEY_ID(source_id);
535    TEST_USES_KEY_ID(target_id);
536
537    PSA_ASSERT(psa_crypto_init());
538
539    /* Populate the source slot. */
540    psa_set_key_id(&source_attributes, source_id);
541    psa_set_key_lifetime(&source_attributes, source_lifetime);
542
543    psa_set_key_type(&source_attributes, source_type);
544    psa_set_key_usage_flags(&source_attributes, source_usage);
545    psa_set_key_algorithm(&source_attributes, source_alg);
546    psa_set_key_enrollment_algorithm(&source_attributes, source_alg2_arg);
547    PSA_ASSERT(psa_import_key(&source_attributes,
548                              material->x, material->len,
549                              &returned_source_id));
550    /* Update the attributes with the bit size. */
551    PSA_ASSERT(psa_get_key_attributes(returned_source_id,
552                                      &source_attributes));
553
554    /* Prepare the target slot. */
555    psa_set_key_id(&target_attributes, target_id);
556    psa_set_key_lifetime(&target_attributes, target_lifetime);
557
558    psa_set_key_usage_flags(&target_attributes, target_usage);
559    psa_set_key_algorithm(&target_attributes, target_alg);
560    psa_set_key_enrollment_algorithm(&target_attributes, target_alg2_arg);
561
562    /* Copy the key. */
563    PSA_ASSERT(psa_copy_key(returned_source_id,
564                            &target_attributes, &returned_target_id));
565
566    /* Destroy the source to ensure that this doesn't affect the target. */
567    PSA_ASSERT(psa_destroy_key(returned_source_id));
568
569    /* If the target key is persistent, restart the system to make
570     * sure that the material is still alive. */
571    if (!PSA_KEY_LIFETIME_IS_VOLATILE(target_lifetime)) {
572        mbedtls_psa_crypto_free();
573        PSA_ASSERT(psa_crypto_init());
574        PSA_ASSERT(psa_open_key(target_id, &target_handle));
575    }
576
577    /* Test that the target slot has the expected content. */
578    psa_reset_key_attributes(&target_attributes);
579    PSA_ASSERT(psa_get_key_attributes(returned_target_id,
580                                      &target_attributes));
581
582    if (!PSA_KEY_LIFETIME_IS_VOLATILE(target_lifetime)) {
583        TEST_ASSERT(mbedtls_svc_key_id_equal(
584                        target_id, psa_get_key_id(&target_attributes)));
585    } else {
586#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
587        TEST_EQUAL(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(returned_target_id),
588                   target_owner_id_arg);
589#endif
590    }
591
592    TEST_EQUAL(target_lifetime, psa_get_key_lifetime(&target_attributes));
593    TEST_EQUAL(source_type, psa_get_key_type(&target_attributes));
594    TEST_EQUAL(psa_get_key_bits(&source_attributes),
595               psa_get_key_bits(&target_attributes));
596    TEST_EQUAL(expected_usage, psa_get_key_usage_flags(&target_attributes));
597    TEST_EQUAL(expected_alg, psa_get_key_algorithm(&target_attributes));
598    TEST_EQUAL(expected_alg2,
599               psa_get_key_enrollment_algorithm(&target_attributes));
600    if (expected_usage & PSA_KEY_USAGE_EXPORT) {
601        size_t length;
602        TEST_CALLOC(export_buffer, material->len);
603        PSA_ASSERT(psa_export_key(returned_target_id, export_buffer,
604                                  material->len, &length));
605        TEST_MEMORY_COMPARE(material->x, material->len,
606                            export_buffer, length);
607    } else {
608        size_t length;
609        /* Check that the key is actually non-exportable. */
610        TEST_EQUAL(psa_export_key(returned_target_id, export_buffer,
611                                  material->len, &length),
612                   PSA_ERROR_NOT_PERMITTED);
613    }
614
615    PSA_ASSERT(psa_destroy_key(returned_target_id));
616
617exit:
618    /*
619     * Source and target key attributes may have been returned by
620     * psa_get_key_attributes() thus reset them as required.
621     */
622    psa_reset_key_attributes(&source_attributes);
623    psa_reset_key_attributes(&target_attributes);
624
625    PSA_DONE();
626    mbedtls_free(export_buffer);
627}
628/* END_CASE */
629
630/* BEGIN_CASE */
631void copy_to_occupied(int source_lifetime_arg, int source_id_arg,
632                      int source_usage_arg, int source_alg_arg,
633                      int source_type_arg, data_t *source_material,
634                      int target_lifetime_arg, int target_id_arg,
635                      int target_usage_arg, int target_alg_arg,
636                      int target_type_arg, data_t *target_material)
637{
638    psa_key_lifetime_t source_lifetime = source_lifetime_arg;
639    mbedtls_svc_key_id_t source_id =
640        mbedtls_svc_key_id_make(1, source_id_arg);
641    psa_key_usage_t source_usage = source_usage_arg;
642    psa_algorithm_t source_alg = source_alg_arg;
643    psa_key_type_t source_type = source_type_arg;
644    mbedtls_svc_key_id_t returned_source_id = MBEDTLS_SVC_KEY_ID_INIT;
645    psa_key_lifetime_t target_lifetime = target_lifetime_arg;
646    mbedtls_svc_key_id_t target_id =
647        mbedtls_svc_key_id_make(1, target_id_arg);
648    psa_key_usage_t target_usage = target_usage_arg;
649    psa_algorithm_t target_alg = target_alg_arg;
650    psa_key_type_t target_type = target_type_arg;
651    mbedtls_svc_key_id_t returned_target_id = MBEDTLS_SVC_KEY_ID_INIT;
652    mbedtls_svc_key_id_t new_key = MBEDTLS_SVC_KEY_ID_INIT;
653    uint8_t *export_buffer = NULL;
654    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
655    psa_key_attributes_t attributes1 = PSA_KEY_ATTRIBUTES_INIT;
656    psa_key_attributes_t attributes2 = PSA_KEY_ATTRIBUTES_INIT;
657
658    TEST_USES_KEY_ID(source_id);
659    TEST_USES_KEY_ID(target_id);
660
661    PSA_ASSERT(psa_crypto_init());
662
663    /* Populate the source slot. */
664    if (!PSA_KEY_LIFETIME_IS_VOLATILE(source_lifetime)) {
665        psa_set_key_id(&attributes, source_id);
666        psa_set_key_lifetime(&attributes, source_lifetime);
667    }
668    psa_set_key_type(&attributes, source_type);
669    psa_set_key_usage_flags(&attributes, source_usage);
670    psa_set_key_algorithm(&attributes, source_alg);
671    PSA_ASSERT(psa_import_key(&attributes,
672                              source_material->x, source_material->len,
673                              &returned_source_id));
674
675    /* Populate the target slot. */
676    if (mbedtls_svc_key_id_equal(target_id, source_id)) {
677        returned_target_id = returned_source_id;
678    } else {
679        psa_set_key_id(&attributes1, target_id);
680        psa_set_key_lifetime(&attributes1, target_lifetime);
681        psa_set_key_type(&attributes1, target_type);
682        psa_set_key_usage_flags(&attributes1, target_usage);
683        psa_set_key_algorithm(&attributes1, target_alg);
684        PSA_ASSERT(psa_import_key(&attributes1,
685                                  target_material->x, target_material->len,
686                                  &returned_target_id));
687    }
688
689    PSA_ASSERT(psa_get_key_attributes(returned_target_id, &attributes1));
690
691    /* Make a copy attempt. */
692    psa_set_key_id(&attributes, target_id);
693    psa_set_key_lifetime(&attributes, target_lifetime);
694    TEST_EQUAL(psa_copy_key(returned_source_id,
695                            &attributes, &new_key),
696               PSA_ERROR_ALREADY_EXISTS);
697    TEST_ASSERT(mbedtls_svc_key_id_is_null(new_key));
698
699    /* Test that the target slot is unaffected. */
700    PSA_ASSERT(psa_get_key_attributes(returned_target_id, &attributes2));
701    TEST_ASSERT(mbedtls_svc_key_id_equal(
702                    psa_get_key_id(&attributes1),
703                    psa_get_key_id(&attributes2)));
704    TEST_EQUAL(psa_get_key_lifetime(&attributes1),
705               psa_get_key_lifetime(&attributes2));
706    TEST_EQUAL(psa_get_key_type(&attributes1),
707               psa_get_key_type(&attributes2));
708    TEST_EQUAL(psa_get_key_bits(&attributes1),
709               psa_get_key_bits(&attributes2));
710    TEST_EQUAL(psa_get_key_usage_flags(&attributes1),
711               psa_get_key_usage_flags(&attributes2));
712    TEST_EQUAL(psa_get_key_algorithm(&attributes1),
713               psa_get_key_algorithm(&attributes2));
714    if (target_usage & PSA_KEY_USAGE_EXPORT) {
715        size_t length;
716        TEST_CALLOC(export_buffer, target_material->len);
717        PSA_ASSERT(psa_export_key(returned_target_id, export_buffer,
718                                  target_material->len, &length));
719        TEST_MEMORY_COMPARE(target_material->x, target_material->len,
720                            export_buffer, length);
721    }
722
723    PSA_ASSERT(psa_destroy_key(returned_source_id));
724    if (!mbedtls_svc_key_id_equal(target_id, source_id)) {
725        PSA_ASSERT(psa_destroy_key(returned_target_id));
726    }
727
728exit:
729    /*
730     * Key attributes may have been returned by psa_get_key_attributes()
731     * thus reset them as required.
732     */
733    psa_reset_key_attributes(&attributes1);
734    psa_reset_key_attributes(&attributes2);
735
736    PSA_DONE();
737    mbedtls_free(export_buffer);
738}
739/* END_CASE */
740
741/* BEGIN_CASE */
742void invalid_handle(int handle_construction,
743                    int close_status_arg)
744{
745    psa_key_handle_t valid_handle = PSA_KEY_HANDLE_INIT;
746    psa_key_handle_t invalid_handle = PSA_KEY_HANDLE_INIT;
747    psa_key_id_t key_id;
748    psa_status_t close_status = close_status_arg;
749    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
750    uint8_t material[1] = "a";
751
752    PSA_ASSERT(psa_crypto_init());
753
754    /* Allocate a handle and store a key in it. */
755    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
756    psa_set_key_usage_flags(&attributes, 0);
757    psa_set_key_algorithm(&attributes, 0);
758    PSA_ASSERT(psa_import_key(&attributes,
759                              material, sizeof(material),
760                              &valid_handle));
761    TEST_ASSERT(!psa_key_handle_is_null(valid_handle));
762
763    /* Construct an invalid handle as specified in the test case data. */
764    switch (handle_construction) {
765        case INVALID_HANDLE_0:
766            invalid_handle = PSA_KEY_HANDLE_INIT;
767            break;
768        case INVALID_HANDLE_UNOPENED:
769
770            /*
771             * MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile
772             * key identifier as the imported key is a volatile key. Volatile
773             * key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN
774             * to PSA_KEY_ID_VOLATILE_MAX included. It is very unlikely that
775             * all IDs are used up to the last one, so pick
776             * PSA_KEY_ID_VOLATILE_MAX to build an unopened and thus invalid
777             * identifier.
778             */
779            key_id = PSA_KEY_ID_VOLATILE_MAX;
780
781            invalid_handle =
782                mbedtls_svc_key_id_make(0, key_id);
783            break;
784        case INVALID_HANDLE_CLOSED:
785            PSA_ASSERT(psa_import_key(&attributes,
786                                      material, sizeof(material),
787                                      &invalid_handle));
788            PSA_ASSERT(psa_destroy_key(invalid_handle));
789            break;
790        case INVALID_HANDLE_HUGE:
791            invalid_handle =
792                mbedtls_svc_key_id_make(0, PSA_KEY_ID_VENDOR_MAX + 1);
793            break;
794        default:
795            TEST_FAIL("unknown handle construction");
796    }
797
798    /* Attempt to use the invalid handle. */
799    TEST_EQUAL(psa_get_key_attributes(invalid_handle, &attributes),
800               PSA_ERROR_INVALID_HANDLE);
801    TEST_EQUAL(psa_close_key(invalid_handle), close_status);
802    TEST_EQUAL(psa_destroy_key(invalid_handle), close_status);
803
804    /* After all this, check that the original handle is intact. */
805    PSA_ASSERT(psa_get_key_attributes(valid_handle, &attributes));
806    TEST_EQUAL(psa_get_key_type(&attributes), PSA_KEY_TYPE_RAW_DATA);
807    TEST_EQUAL(psa_get_key_bits(&attributes),
808               PSA_BYTES_TO_BITS(sizeof(material)));
809    PSA_ASSERT(psa_close_key(valid_handle));
810
811exit:
812    /*
813     * Key attributes may have been returned by psa_get_key_attributes()
814     * thus reset them as required.
815     */
816    psa_reset_key_attributes(&attributes);
817
818    PSA_DONE();
819}
820/* END_CASE */
821
822/* BEGIN_CASE */
823void many_transient_keys(int max_keys_arg)
824{
825    mbedtls_svc_key_id_t *keys = NULL;
826    size_t max_keys = max_keys_arg;
827    size_t i, j;
828    psa_status_t status;
829    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
830    uint8_t exported[sizeof(size_t)];
831    size_t exported_length;
832
833    TEST_CALLOC(keys, max_keys);
834    PSA_ASSERT(psa_crypto_init());
835
836    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
837    psa_set_key_algorithm(&attributes, 0);
838    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
839
840    for (i = 0; i < max_keys; i++) {
841        mbedtls_test_set_step(i);
842        status = psa_import_key(&attributes,
843                                (uint8_t *) &i, sizeof(i),
844                                &keys[i]);
845        PSA_ASSERT(status);
846        TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i]));
847        for (j = 0; j < i; j++) {
848            TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j]));
849        }
850    }
851
852    for (i = 1; i < max_keys; i++) {
853        mbedtls_test_set_step(i);
854        PSA_ASSERT(psa_close_key(keys[i - 1]));
855        PSA_ASSERT(psa_export_key(keys[i],
856                                  exported, sizeof(exported),
857                                  &exported_length));
858        TEST_MEMORY_COMPARE(exported, exported_length,
859                            (uint8_t *) &i, sizeof(i));
860    }
861    PSA_ASSERT(psa_close_key(keys[i - 1]));
862
863exit:
864    PSA_DONE();
865    mbedtls_free(keys);
866}
867/* END_CASE */
868
869/* BEGIN_CASE depends_on:MAX_VOLATILE_KEYS */
870/*
871 * 1. Fill the key store with volatile keys.
872 * 2. Check that attempting to create another volatile key fails without
873 *    corrupting the key store.
874 * 3. Destroy the key specified by key_to_destroy. This is the number of the
875 *    key in creation order (e.g. 0 means the first key that was created).
876 *    It can also  be a negative value to count in reverse order (e.g.
877 *    -1 means to destroy the last key that was created).
878 * 4. Check that creating another volatile key succeeds.
879 */
880void fill_key_store(int key_to_destroy_arg)
881{
882    mbedtls_svc_key_id_t *keys = NULL;
883    size_t max_keys = MAX_VOLATILE_KEYS;
884    size_t i, j;
885    psa_status_t status;
886    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
887    uint8_t exported[sizeof(size_t)];
888    size_t exported_length;
889
890#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
891    mbedtls_test_hook_psa_volatile_key_slice_length = &tiny_key_slice_length;
892#endif
893
894    PSA_ASSERT(psa_crypto_init());
895
896    mbedtls_psa_stats_t stats;
897    mbedtls_psa_get_stats(&stats);
898    /* Account for any system-created volatile key, e.g. for the RNG. */
899    max_keys -= stats.volatile_slots;
900    TEST_CALLOC(keys, max_keys + 1);
901
902    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
903    psa_set_key_algorithm(&attributes, 0);
904    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
905
906    /* Fill the key store. */
907    for (i = 0; i < max_keys; i++) {
908        mbedtls_test_set_step(i);
909        status = psa_import_key(&attributes,
910                                (uint8_t *) &i, sizeof(i),
911                                &keys[i]);
912        PSA_ASSERT(status);
913        TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i]));
914        for (j = 0; j < i; j++) {
915            TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j]));
916        }
917    }
918
919    /* Attempt to overfill. */
920    mbedtls_test_set_step(max_keys);
921    status = psa_import_key(&attributes,
922                            (uint8_t *) &max_keys, sizeof(max_keys),
923                            &keys[max_keys]);
924    TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
925    TEST_ASSERT(mbedtls_svc_key_id_is_null(keys[max_keys]));
926
927    /* Check that the keys are not corrupted. */
928    for (i = 0; i < max_keys; i++) {
929        mbedtls_test_set_step(i);
930        PSA_ASSERT(psa_export_key(keys[i],
931                                  exported, sizeof(exported),
932                                  &exported_length));
933        TEST_MEMORY_COMPARE(exported, exported_length,
934                            (uint8_t *) &i, sizeof(i));
935    }
936
937    /* Destroy one key and try again. */
938    size_t key_to_destroy = (key_to_destroy_arg >= 0 ?
939                             (size_t) key_to_destroy_arg :
940                             max_keys + key_to_destroy_arg);
941    mbedtls_svc_key_id_t reused_id = keys[key_to_destroy];
942    const uint8_t replacement_value[1] = { 0x64 };
943    PSA_ASSERT(psa_destroy_key(keys[key_to_destroy]));
944    keys[key_to_destroy] = MBEDTLS_SVC_KEY_ID_INIT;
945    status = psa_import_key(&attributes,
946                            replacement_value, sizeof(replacement_value),
947                            &keys[key_to_destroy]);
948    PSA_ASSERT(status);
949    /* Since the key store was full except for one key, the new key must be
950     * in the same slot in the key store as the destroyed key.
951     * Since volatile keys IDs are assigned based on which slot contains
952     * the key, the new key should have the same ID as the destroyed key.
953     */
954    TEST_ASSERT(mbedtls_svc_key_id_equal(reused_id, keys[key_to_destroy]));
955
956    /* Check that the keys are not corrupted and destroy them. */
957    for (i = 0; i < max_keys; i++) {
958        mbedtls_test_set_step(i);
959        PSA_ASSERT(psa_export_key(keys[i],
960                                  exported, sizeof(exported),
961                                  &exported_length));
962        if (i == key_to_destroy) {
963            TEST_MEMORY_COMPARE(exported, exported_length,
964                                replacement_value, sizeof(replacement_value));
965        } else {
966            TEST_MEMORY_COMPARE(exported, exported_length,
967                                (uint8_t *) &i, sizeof(i));
968        }
969        PSA_ASSERT(psa_destroy_key(keys[i]));
970        keys[i] = MBEDTLS_SVC_KEY_ID_INIT;
971    }
972
973exit:
974    PSA_DONE();
975    mbedtls_free(keys);
976#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && defined(MBEDTLS_TEST_HOOKS)
977    mbedtls_test_hook_psa_volatile_key_slice_length = NULL;
978#endif
979}
980/* END_CASE */
981
982/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
983void key_slot_eviction_to_import_new_key(int lifetime_arg)
984{
985    psa_key_lifetime_t lifetime = (psa_key_lifetime_t) lifetime_arg;
986    size_t i;
987    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
988    uint8_t exported[sizeof(size_t)];
989    size_t exported_length;
990    mbedtls_svc_key_id_t key, returned_key_id;
991
992    PSA_ASSERT(psa_crypto_init());
993
994    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
995    psa_set_key_algorithm(&attributes, 0);
996    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
997
998    /*
999     * Create MBEDTLS_PSA_KEY_SLOT_COUNT persistent keys.
1000     */
1001    for (i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
1002        key = mbedtls_svc_key_id_make(i, i + 1);
1003        psa_set_key_id(&attributes, key);
1004        PSA_ASSERT(psa_import_key(&attributes,
1005                                  (uint8_t *) &i, sizeof(i),
1006                                  &returned_key_id));
1007        TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key));
1008    }
1009
1010    /*
1011     * Create a new persistent or volatile key. When creating the key,
1012     * one of the descriptions of the previously created persistent keys
1013     * is removed from the RAM key slots. This makes room to store its
1014     * description in RAM.
1015     */
1016    i = MBEDTLS_PSA_KEY_SLOT_COUNT;
1017    key = mbedtls_svc_key_id_make(i, i + 1);
1018    psa_set_key_id(&attributes, key);
1019    psa_set_key_lifetime(&attributes, lifetime);
1020
1021    PSA_ASSERT(psa_import_key(&attributes,
1022                              (uint8_t *) &i, sizeof(i),
1023                              &returned_key_id));
1024    if (lifetime != PSA_KEY_LIFETIME_VOLATILE) {
1025        TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key));
1026    } else {
1027        TEST_ASSERT(psa_key_id_is_volatile(
1028                        MBEDTLS_SVC_KEY_ID_GET_KEY_ID(returned_key_id)));
1029    }
1030
1031    /*
1032     * Check that we can export all ( MBEDTLS_PSA_KEY_SLOT_COUNT + 1 ) keys,
1033     * that they have the expected value and destroy them. In that process,
1034     * the description of the persistent key that was evicted from the RAM
1035     * slots when creating the last key is restored in a RAM slot to export
1036     * its value.
1037     */
1038    for (i = 0; i <= MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
1039        if (i < MBEDTLS_PSA_KEY_SLOT_COUNT) {
1040            key = mbedtls_svc_key_id_make(i, i + 1);
1041        } else {
1042            key = returned_key_id;
1043        }
1044
1045        PSA_ASSERT(psa_export_key(key,
1046                                  exported, sizeof(exported),
1047                                  &exported_length));
1048        TEST_MEMORY_COMPARE(exported, exported_length,
1049                            (uint8_t *) &i, sizeof(i));
1050        PSA_ASSERT(psa_destroy_key(key));
1051    }
1052
1053exit:
1054    PSA_DONE();
1055}
1056/* END_CASE */
1057
1058/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C:!MBEDTLS_PSA_KEY_STORE_DYNAMIC */
1059void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
1060{
1061    psa_status_t status;
1062    size_t i;
1063    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
1064    uint8_t exported[sizeof(size_t)];
1065    size_t exported_length;
1066    mbedtls_svc_key_id_t persistent_key = MBEDTLS_SVC_KEY_ID_INIT;
1067    mbedtls_svc_key_id_t persistent_key2 = MBEDTLS_SVC_KEY_ID_INIT;
1068    mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
1069    mbedtls_svc_key_id_t *keys = NULL;
1070    mbedtls_psa_stats_t psa_key_slots_stats;
1071    size_t available_key_slots = 0;
1072
1073    TEST_ASSERT(MBEDTLS_PSA_KEY_SLOT_COUNT >= 1);
1074
1075    PSA_ASSERT(psa_crypto_init());
1076    mbedtls_psa_get_stats(&psa_key_slots_stats);
1077    available_key_slots = psa_key_slots_stats.empty_slots;
1078
1079    TEST_CALLOC(keys, available_key_slots);
1080
1081    psa_set_key_usage_flags(&attributes,
1082                            PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY);
1083    psa_set_key_algorithm(&attributes, 0);
1084    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
1085
1086    /*
1087     * Create a persistent key
1088     */
1089    persistent_key = mbedtls_svc_key_id_make(0x100, 0x205);
1090    psa_set_key_id(&attributes, persistent_key);
1091    PSA_ASSERT(psa_import_key(&attributes,
1092                              (uint8_t *) &persistent_key,
1093                              sizeof(persistent_key),
1094                              &returned_key_id));
1095    TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, persistent_key));
1096
1097    /*
1098     * Create the maximum available number of keys that are locked in
1099     * memory. This can be:
1100     * - volatile keys, when MBEDTLS_PSA_KEY_STORE_DYNAMIC is disabled;
1101     * - opened persistent keys (could work, but not currently implemented
1102     *   in this test function);
1103     * - keys in use by another thread (we don't do this because it would
1104     *   be hard to arrange and we can't control how long the keys are
1105     *   locked anyway).
1106     */
1107    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
1108    for (i = 0; i < available_key_slots; i++) {
1109        PSA_ASSERT(psa_import_key(&attributes,
1110                                  (uint8_t *) &i, sizeof(i),
1111                                  &keys[i]));
1112    }
1113    psa_reset_key_attributes(&attributes);
1114
1115    /*
1116     * Check that we cannot access the persistent key as all slots are
1117     * occupied by volatile keys and the implementation needs to load the
1118     * persistent key description in a slot to be able to access it.
1119     */
1120    status = psa_get_key_attributes(persistent_key, &attributes);
1121    TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
1122
1123    /*
1124     * Check we can export the volatile key created last and that it has the
1125     * expected value. Then, destroy it.
1126     */
1127    PSA_ASSERT(psa_export_key(keys[available_key_slots - 1],
1128                              exported, sizeof(exported),
1129                              &exported_length));
1130    i = available_key_slots - 1;
1131    TEST_MEMORY_COMPARE(exported, exported_length, (uint8_t *) &i, sizeof(i));
1132    PSA_ASSERT(psa_destroy_key(keys[available_key_slots - 1]));
1133
1134    /*
1135     * Check that we can now access the persistent key again.
1136     */
1137    PSA_ASSERT(psa_get_key_attributes(persistent_key, &attributes));
1138    TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.id,
1139                                         persistent_key));
1140
1141    /*
1142     * Check that we cannot copy the persistent key as all slots are occupied
1143     * by the persistent key and the volatile keys and the slot containing the
1144     * persistent key cannot be reclaimed as it contains the key to copy.
1145     */
1146    persistent_key2 = mbedtls_svc_key_id_make(0x100, 0x204);
1147    psa_set_key_id(&attributes, persistent_key2);
1148    status = psa_copy_key(persistent_key, &attributes, &returned_key_id);
1149    TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
1150
1151    /*
1152     * Check we can export the remaining volatile keys and that they have the
1153     * expected values.
1154     */
1155    for (i = 0; i < (available_key_slots - 1); i++) {
1156        PSA_ASSERT(psa_export_key(keys[i],
1157                                  exported, sizeof(exported),
1158                                  &exported_length));
1159        TEST_MEMORY_COMPARE(exported, exported_length,
1160                            (uint8_t *) &i, sizeof(i));
1161        PSA_ASSERT(psa_destroy_key(keys[i]));
1162    }
1163
1164    /*
1165     * Check we can export the persistent key and that it have the expected
1166     * value.
1167     */
1168
1169    PSA_ASSERT(psa_export_key(persistent_key, exported, sizeof(exported),
1170                              &exported_length));
1171    TEST_MEMORY_COMPARE(exported, exported_length,
1172                        (uint8_t *) &persistent_key, sizeof(persistent_key));
1173exit:
1174    /*
1175     * Key attributes may have been returned by psa_get_key_attributes()
1176     * thus reset them as required.
1177     */
1178    psa_reset_key_attributes(&attributes);
1179
1180    psa_destroy_key(persistent_key);
1181    PSA_DONE();
1182    mbedtls_free(keys);
1183}
1184/* END_CASE */
1185