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/* END_HEADER */
102
103/* BEGIN_DEPENDENCIES
104 * depends_on:MBEDTLS_PSA_CRYPTO_C
105 * END_DEPENDENCIES
106 */
107
108/* BEGIN_CASE */
109void transient_slot_lifecycle(int owner_id_arg,
110                              int usage_arg, int alg_arg,
111                              int type_arg, data_t *key_data,
112                              int invalidate_method_arg)
113{
114    psa_algorithm_t alg = alg_arg;
115    psa_key_usage_t usage_flags = usage_arg;
116    psa_key_type_t type = type_arg;
117    invalidate_method_t invalidate_method = invalidate_method_arg;
118    mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
119    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
120
121    mbedtls_test_set_step(1);
122    PSA_ASSERT(psa_crypto_init());
123
124    /* Import a key. */
125#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
126    mbedtls_key_owner_id_t owner_id = owner_id_arg;
127
128    mbedtls_set_key_owner_id(&attributes, owner_id);
129#else
130    (void) owner_id_arg;
131#endif
132
133    psa_set_key_usage_flags(&attributes, usage_flags);
134    psa_set_key_algorithm(&attributes, alg);
135    psa_set_key_type(&attributes, type);
136    PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
137                              &key));
138    TEST_ASSERT(!mbedtls_svc_key_id_is_null(key));
139    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
140    TEST_EQUAL(psa_get_key_type(&attributes), type);
141    psa_reset_key_attributes(&attributes);
142
143#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
144    {
145        psa_key_handle_t handle;
146        mbedtls_svc_key_id_t key_with_invalid_owner =
147            mbedtls_svc_key_id_make(owner_id + 1,
148                                    MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key));
149
150        TEST_ASSERT(mbedtls_key_owner_id_equal(
151                        owner_id,
152                        MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(key)));
153        TEST_EQUAL(psa_open_key(key_with_invalid_owner, &handle),
154                   PSA_ERROR_DOES_NOT_EXIST);
155    }
156#endif
157
158    /*
159     * Purge the key and make sure that it is still valid, as purging a
160     * volatile key shouldn't invalidate/destroy it.
161     */
162    PSA_ASSERT(psa_purge_key(key));
163    PSA_ASSERT(psa_get_key_attributes(key, &attributes));
164    TEST_EQUAL(psa_get_key_type(&attributes), type);
165    psa_reset_key_attributes(&attributes);
166
167    /* Do something that invalidates the key. */
168    mbedtls_test_set_step(2);
169    if (!invalidate_key(invalidate_method, key)) {
170        goto exit;
171    }
172    if (!invalidate_psa(invalidate_method)) {
173        goto exit;
174    }
175
176    /* Test that the key is now invalid. */
177    TEST_EQUAL(psa_get_key_attributes(key, &attributes),
178               PSA_ERROR_INVALID_HANDLE);
179    TEST_EQUAL(psa_close_key(key), PSA_ERROR_INVALID_HANDLE);
180
181exit:
182    /*
183     * Key attributes may have been returned by psa_get_key_attributes()
184     * thus reset them as required.
185     */
186    psa_reset_key_attributes(&attributes);
187
188    PSA_DONE();
189}
190/* END_CASE */
191
192/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
193void persistent_slot_lifecycle(int lifetime_arg, int owner_id_arg, int id_arg,
194                               int usage_arg, int alg_arg, int alg2_arg,
195                               int type_arg, data_t *key_data,
196                               int invalidate_method_arg)
197{
198    psa_key_lifetime_t lifetime = lifetime_arg;
199    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(owner_id_arg, id_arg);
200    psa_algorithm_t alg = alg_arg;
201    psa_algorithm_t alg2 = alg2_arg;
202    psa_key_usage_t usage_flags = usage_arg;
203    psa_key_type_t type = type_arg;
204    invalidate_method_t invalidate_method = invalidate_method_arg;
205    mbedtls_svc_key_id_t returned_id = MBEDTLS_SVC_KEY_ID_INIT;
206    psa_key_handle_t handle = PSA_KEY_HANDLE_INIT;
207    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
208    psa_key_attributes_t read_attributes = PSA_KEY_ATTRIBUTES_INIT;
209    uint8_t *reexported = NULL;
210    size_t reexported_length = -1;
211
212#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
213    mbedtls_svc_key_id_t wrong_owner_id =
214        mbedtls_svc_key_id_make(owner_id_arg + 1, id_arg);
215    mbedtls_svc_key_id_t invalid_svc_key_id = MBEDTLS_SVC_KEY_ID_INIT;
216#endif
217
218    TEST_USES_KEY_ID(id);
219
220    mbedtls_test_set_step(1);
221    PSA_ASSERT(psa_crypto_init());
222
223    psa_set_key_id(&attributes, id);
224    psa_set_key_lifetime(&attributes, lifetime);
225    psa_set_key_type(&attributes, type);
226    psa_set_key_usage_flags(&attributes, usage_flags);
227    psa_set_key_algorithm(&attributes, alg);
228    psa_set_key_enrollment_algorithm(&attributes, alg2);
229    PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
230                              &returned_id));
231    TEST_ASSERT(mbedtls_svc_key_id_equal(id, returned_id));
232
233#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
234    TEST_EQUAL(psa_open_key(wrong_owner_id, &invalid_svc_key_id),
235               PSA_ERROR_DOES_NOT_EXIST);
236#endif
237
238    PSA_ASSERT(psa_get_key_attributes(id, &attributes));
239    TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
240    TEST_ASSERT(mbedtls_svc_key_id_equal(
241                    psa_get_key_id(&attributes), id));
242    TEST_EQUAL(psa_get_key_usage_flags(&attributes),
243               mbedtls_test_update_key_usage_flags(usage_flags));
244    TEST_EQUAL(psa_get_key_algorithm(&attributes), alg);
245    TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), alg2);
246    TEST_EQUAL(psa_get_key_type(&attributes), type);
247
248    /* Close the key and then open it. */
249    PSA_ASSERT(psa_close_key(id));
250
251#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
252    TEST_EQUAL(psa_open_key(wrong_owner_id, &invalid_svc_key_id),
253               PSA_ERROR_DOES_NOT_EXIST);
254#endif
255
256    PSA_ASSERT(psa_open_key(id, &handle));
257    TEST_ASSERT(!psa_key_handle_is_null(handle));
258    PSA_ASSERT(psa_get_key_attributes(handle, &attributes));
259    TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
260    TEST_ASSERT(mbedtls_svc_key_id_equal(
261                    psa_get_key_id(&attributes), id));
262    TEST_EQUAL(psa_get_key_usage_flags(&attributes),
263               mbedtls_test_update_key_usage_flags(usage_flags));
264    TEST_EQUAL(psa_get_key_algorithm(&attributes), alg);
265    TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), alg2);
266    TEST_EQUAL(psa_get_key_type(&attributes), type);
267
268    /*
269     * Do something that wipes key data in volatile memory or destroy the
270     * key.
271     */
272    mbedtls_test_set_step(2);
273    if (!invalidate_key(invalidate_method, id)) {
274        goto exit;
275    }
276    if (!invalidate_psa(invalidate_method)) {
277        goto exit;
278    }
279
280    /* Try to reaccess the key. If we destroyed it, check that it doesn't
281     * exist. Otherwise check that it still exists and has the expected
282     * content. */
283    switch (invalidate_method) {
284        case INVALIDATE_BY_CLOSING:
285        case INVALIDATE_BY_CLOSING_WITH_SHUTDOWN:
286        case INVALIDATE_BY_PURGING:
287        case INVALIDATE_BY_PURGING_WITH_SHUTDOWN:
288        case INVALIDATE_BY_SHUTDOWN:
289            PSA_ASSERT(psa_open_key(id, &handle));
290            PSA_ASSERT(psa_get_key_attributes(id, &read_attributes));
291            TEST_EQUAL(psa_get_key_lifetime(&attributes),
292                       psa_get_key_lifetime(&read_attributes));
293            TEST_ASSERT(mbedtls_svc_key_id_equal(
294                            psa_get_key_id(&attributes),
295                            psa_get_key_id(&read_attributes)));
296            TEST_EQUAL(psa_get_key_usage_flags(&attributes),
297                       mbedtls_test_update_key_usage_flags(usage_flags));
298            TEST_EQUAL(psa_get_key_algorithm(&attributes),
299                       psa_get_key_algorithm(&read_attributes));
300            TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes),
301                       psa_get_key_enrollment_algorithm(&read_attributes));
302            TEST_EQUAL(psa_get_key_type(&attributes),
303                       psa_get_key_type(&read_attributes));
304            TEST_EQUAL(psa_get_key_bits(&attributes),
305                       psa_get_key_bits(&read_attributes));
306            ASSERT_ALLOC(reexported, key_data->len);
307            if (usage_flags & PSA_KEY_USAGE_EXPORT) {
308                PSA_ASSERT(psa_export_key(id, reexported, key_data->len,
309                                          &reexported_length));
310                ASSERT_COMPARE(key_data->x, key_data->len,
311                               reexported, reexported_length);
312            } else {
313                TEST_EQUAL(psa_export_key(id, reexported,
314                                          key_data->len, &reexported_length),
315                           PSA_ERROR_NOT_PERMITTED);
316            }
317            PSA_ASSERT(psa_close_key(handle));
318            break;
319
320        case INVALIDATE_BY_DESTROYING:
321        case INVALIDATE_BY_DESTROYING_WITH_SHUTDOWN:
322            /*
323             * Test that the key handle and identifier are now not referring to an
324             * existing key.
325             */
326            TEST_EQUAL(psa_get_key_attributes(handle, &read_attributes),
327                       PSA_ERROR_INVALID_HANDLE);
328            TEST_EQUAL(psa_close_key(handle), PSA_ERROR_INVALID_HANDLE);
329            TEST_EQUAL(psa_get_key_attributes(id, &read_attributes),
330                       PSA_ERROR_INVALID_HANDLE);
331            break;
332    }
333
334exit:
335    /*
336     * Key attributes may have been returned by psa_get_key_attributes()
337     * thus reset them as required.
338     */
339    psa_reset_key_attributes(&attributes);
340    psa_reset_key_attributes(&read_attributes);
341
342    PSA_DONE();
343    mbedtls_free(reexported);
344}
345/* END_CASE */
346
347/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
348void create_existent(int lifetime_arg, int owner_id_arg, int id_arg,
349                     int reopen_policy_arg)
350{
351    psa_key_lifetime_t lifetime = lifetime_arg;
352    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(owner_id_arg, id_arg);
353    mbedtls_svc_key_id_t returned_id = MBEDTLS_SVC_KEY_ID_INIT;
354    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
355    psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA;
356    const uint8_t material1[5] = "a key";
357    const uint8_t material2[5] = "b key";
358    size_t bits1 = PSA_BYTES_TO_BITS(sizeof(material1));
359    uint8_t reexported[sizeof(material1)];
360    size_t reexported_length;
361    reopen_policy_t reopen_policy = reopen_policy_arg;
362
363    TEST_USES_KEY_ID(id);
364
365    PSA_ASSERT(psa_crypto_init());
366
367    /* Create a key. */
368    psa_set_key_id(&attributes, id);
369    psa_set_key_lifetime(&attributes, lifetime);
370    psa_set_key_type(&attributes, type1);
371    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
372    psa_set_key_algorithm(&attributes, 0);
373    PSA_ASSERT(psa_import_key(&attributes, material1, sizeof(material1),
374                              &returned_id));
375    TEST_ASSERT(mbedtls_svc_key_id_equal(id, returned_id));
376
377    if (reopen_policy == CLOSE_BEFORE) {
378        PSA_ASSERT(psa_close_key(id));
379    }
380
381    /* Attempt to create a new key in the same slot. */
382    TEST_EQUAL(psa_import_key(&attributes, material2, sizeof(material2),
383                              &returned_id),
384               PSA_ERROR_ALREADY_EXISTS);
385    TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_id));
386
387    if (reopen_policy == CLOSE_AFTER) {
388        PSA_ASSERT(psa_close_key(id));
389    }
390
391    /* Check that the original key hasn't changed. */
392    psa_reset_key_attributes(&attributes);
393    PSA_ASSERT(psa_get_key_attributes(id, &attributes));
394    TEST_ASSERT(mbedtls_svc_key_id_equal(
395                    psa_get_key_id(&attributes), id));
396    TEST_EQUAL(psa_get_key_lifetime(&attributes), lifetime);
397    TEST_EQUAL(psa_get_key_type(&attributes), type1);
398    TEST_EQUAL(psa_get_key_bits(&attributes), bits1);
399    TEST_EQUAL(psa_get_key_usage_flags(&attributes), PSA_KEY_USAGE_EXPORT);
400    TEST_EQUAL(psa_get_key_algorithm(&attributes), 0);
401
402    PSA_ASSERT(psa_export_key(id,
403                              reexported, sizeof(reexported),
404                              &reexported_length));
405    ASSERT_COMPARE(material1, sizeof(material1),
406                   reexported, reexported_length);
407
408    PSA_ASSERT(psa_close_key(id));
409
410exit:
411    /*
412     * Key attributes may have been returned by psa_get_key_attributes()
413     * thus reset them as required.
414     */
415    psa_reset_key_attributes(&attributes);
416
417    PSA_DONE();
418}
419/* END_CASE */
420
421/* BEGIN_CASE */
422void open_fail(int id_arg,
423               int expected_status_arg)
424{
425    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
426    psa_status_t expected_status = expected_status_arg;
427    psa_key_handle_t handle = mbedtls_svc_key_id_make(0xdead, 0xdead);
428
429    PSA_ASSERT(psa_crypto_init());
430
431    TEST_EQUAL(psa_open_key(id, &handle), expected_status);
432    TEST_ASSERT(psa_key_handle_is_null(handle));
433
434exit:
435    PSA_DONE();
436}
437/* END_CASE */
438
439/* BEGIN_CASE */
440void create_fail(int lifetime_arg, int id_arg,
441                 int expected_status_arg)
442{
443    psa_key_lifetime_t lifetime = lifetime_arg;
444    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
445    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
446    psa_status_t expected_status = expected_status_arg;
447    mbedtls_svc_key_id_t returned_id =
448        mbedtls_svc_key_id_make(0xdead, 0xdead);
449    uint8_t material[1] = { 'k' };
450
451    TEST_USES_KEY_ID(id);
452
453    PSA_ASSERT(psa_crypto_init());
454
455    psa_set_key_lifetime(&attributes, lifetime);
456    if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
457        /*
458         * Not possible to set a key identifier different from 0 through
459         * PSA key attributes APIs thus accessing to the attributes
460         * directly.
461         */
462        attributes.core.id = id;
463    } else {
464        psa_set_key_id(&attributes, id);
465    }
466
467    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
468    TEST_EQUAL(psa_import_key(&attributes, material, sizeof(material),
469                              &returned_id),
470               expected_status);
471    TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_id));
472
473exit:
474    PSA_DONE();
475}
476/* END_CASE */
477
478/* BEGIN_CASE */
479void copy_across_lifetimes(int source_lifetime_arg, int source_owner_id_arg,
480                           int source_id_arg, int source_usage_arg,
481                           int source_alg_arg, int source_alg2_arg,
482                           int type_arg, data_t *material,
483                           int target_lifetime_arg, int target_owner_id_arg,
484                           int target_id_arg, int target_usage_arg,
485                           int target_alg_arg, int target_alg2_arg,
486                           int expected_usage_arg,
487                           int expected_alg_arg, int expected_alg2_arg)
488{
489    psa_key_lifetime_t source_lifetime = source_lifetime_arg;
490    mbedtls_svc_key_id_t source_id =
491        mbedtls_svc_key_id_make(source_owner_id_arg, source_id_arg);
492    psa_key_usage_t source_usage = source_usage_arg;
493    psa_algorithm_t source_alg = source_alg_arg;
494    psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
495    psa_key_type_t source_type = type_arg;
496    mbedtls_svc_key_id_t returned_source_id = MBEDTLS_SVC_KEY_ID_INIT;
497    psa_key_lifetime_t target_lifetime = target_lifetime_arg;
498    mbedtls_svc_key_id_t target_id =
499        mbedtls_svc_key_id_make(target_owner_id_arg, target_id_arg);
500    psa_key_usage_t target_usage = target_usage_arg;
501    psa_algorithm_t target_alg = target_alg_arg;
502    psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
503    mbedtls_svc_key_id_t returned_target_id = MBEDTLS_SVC_KEY_ID_INIT;
504    psa_key_handle_t target_handle = PSA_KEY_HANDLE_INIT;
505    psa_key_usage_t expected_usage = expected_usage_arg;
506    psa_algorithm_t expected_alg = expected_alg_arg;
507    psa_algorithm_t expected_alg2 = expected_alg2_arg;
508    uint8_t *export_buffer = NULL;
509
510    TEST_USES_KEY_ID(source_id);
511    TEST_USES_KEY_ID(target_id);
512
513    PSA_ASSERT(psa_crypto_init());
514
515    /* Populate the source slot. */
516    psa_set_key_id(&source_attributes, source_id);
517    psa_set_key_lifetime(&source_attributes, source_lifetime);
518
519    psa_set_key_type(&source_attributes, source_type);
520    psa_set_key_usage_flags(&source_attributes, source_usage);
521    psa_set_key_algorithm(&source_attributes, source_alg);
522    psa_set_key_enrollment_algorithm(&source_attributes, source_alg2_arg);
523    PSA_ASSERT(psa_import_key(&source_attributes,
524                              material->x, material->len,
525                              &returned_source_id));
526    /* Update the attributes with the bit size. */
527    PSA_ASSERT(psa_get_key_attributes(returned_source_id,
528                                      &source_attributes));
529
530    /* Prepare the target slot. */
531    psa_set_key_id(&target_attributes, target_id);
532    psa_set_key_lifetime(&target_attributes, target_lifetime);
533
534    psa_set_key_usage_flags(&target_attributes, target_usage);
535    psa_set_key_algorithm(&target_attributes, target_alg);
536    psa_set_key_enrollment_algorithm(&target_attributes, target_alg2_arg);
537
538    /* Copy the key. */
539    PSA_ASSERT(psa_copy_key(returned_source_id,
540                            &target_attributes, &returned_target_id));
541
542    /* Destroy the source to ensure that this doesn't affect the target. */
543    PSA_ASSERT(psa_destroy_key(returned_source_id));
544
545    /* If the target key is persistent, restart the system to make
546     * sure that the material is still alive. */
547    if (!PSA_KEY_LIFETIME_IS_VOLATILE(target_lifetime)) {
548        mbedtls_psa_crypto_free();
549        PSA_ASSERT(psa_crypto_init());
550        PSA_ASSERT(psa_open_key(target_id, &target_handle));
551    }
552
553    /* Test that the target slot has the expected content. */
554    psa_reset_key_attributes(&target_attributes);
555    PSA_ASSERT(psa_get_key_attributes(returned_target_id,
556                                      &target_attributes));
557
558    if (!PSA_KEY_LIFETIME_IS_VOLATILE(target_lifetime)) {
559        TEST_ASSERT(mbedtls_svc_key_id_equal(
560                        target_id, psa_get_key_id(&target_attributes)));
561    } else {
562#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
563        TEST_EQUAL(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(returned_target_id),
564                   target_owner_id_arg);
565#endif
566    }
567
568    TEST_EQUAL(target_lifetime, psa_get_key_lifetime(&target_attributes));
569    TEST_EQUAL(source_type, psa_get_key_type(&target_attributes));
570    TEST_EQUAL(psa_get_key_bits(&source_attributes),
571               psa_get_key_bits(&target_attributes));
572    TEST_EQUAL(expected_usage, psa_get_key_usage_flags(&target_attributes));
573    TEST_EQUAL(expected_alg, psa_get_key_algorithm(&target_attributes));
574    TEST_EQUAL(expected_alg2,
575               psa_get_key_enrollment_algorithm(&target_attributes));
576    if (expected_usage & PSA_KEY_USAGE_EXPORT) {
577        size_t length;
578        ASSERT_ALLOC(export_buffer, material->len);
579        PSA_ASSERT(psa_export_key(returned_target_id, export_buffer,
580                                  material->len, &length));
581        ASSERT_COMPARE(material->x, material->len,
582                       export_buffer, length);
583    } else {
584        size_t length;
585        /* Check that the key is actually non-exportable. */
586        TEST_EQUAL(psa_export_key(returned_target_id, export_buffer,
587                                  material->len, &length),
588                   PSA_ERROR_NOT_PERMITTED);
589    }
590
591    PSA_ASSERT(psa_destroy_key(returned_target_id));
592
593exit:
594    /*
595     * Source and target key attributes may have been returned by
596     * psa_get_key_attributes() thus reset them as required.
597     */
598    psa_reset_key_attributes(&source_attributes);
599    psa_reset_key_attributes(&target_attributes);
600
601    PSA_DONE();
602    mbedtls_free(export_buffer);
603}
604/* END_CASE */
605
606/* BEGIN_CASE */
607void copy_to_occupied(int source_lifetime_arg, int source_id_arg,
608                      int source_usage_arg, int source_alg_arg,
609                      int source_type_arg, data_t *source_material,
610                      int target_lifetime_arg, int target_id_arg,
611                      int target_usage_arg, int target_alg_arg,
612                      int target_type_arg, data_t *target_material)
613{
614    psa_key_lifetime_t source_lifetime = source_lifetime_arg;
615    mbedtls_svc_key_id_t source_id =
616        mbedtls_svc_key_id_make(1, source_id_arg);
617    psa_key_usage_t source_usage = source_usage_arg;
618    psa_algorithm_t source_alg = source_alg_arg;
619    psa_key_type_t source_type = source_type_arg;
620    mbedtls_svc_key_id_t returned_source_id = MBEDTLS_SVC_KEY_ID_INIT;
621    psa_key_lifetime_t target_lifetime = target_lifetime_arg;
622    mbedtls_svc_key_id_t target_id =
623        mbedtls_svc_key_id_make(1, target_id_arg);
624    psa_key_usage_t target_usage = target_usage_arg;
625    psa_algorithm_t target_alg = target_alg_arg;
626    psa_key_type_t target_type = target_type_arg;
627    mbedtls_svc_key_id_t returned_target_id = MBEDTLS_SVC_KEY_ID_INIT;
628    mbedtls_svc_key_id_t new_key = MBEDTLS_SVC_KEY_ID_INIT;
629    uint8_t *export_buffer = NULL;
630    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
631    psa_key_attributes_t attributes1 = PSA_KEY_ATTRIBUTES_INIT;
632    psa_key_attributes_t attributes2 = PSA_KEY_ATTRIBUTES_INIT;
633
634    TEST_USES_KEY_ID(source_id);
635    TEST_USES_KEY_ID(target_id);
636
637    PSA_ASSERT(psa_crypto_init());
638
639    /* Populate the source slot. */
640    if (!PSA_KEY_LIFETIME_IS_VOLATILE(source_lifetime)) {
641        psa_set_key_id(&attributes, source_id);
642        psa_set_key_lifetime(&attributes, source_lifetime);
643    }
644    psa_set_key_type(&attributes, source_type);
645    psa_set_key_usage_flags(&attributes, source_usage);
646    psa_set_key_algorithm(&attributes, source_alg);
647    PSA_ASSERT(psa_import_key(&attributes,
648                              source_material->x, source_material->len,
649                              &returned_source_id));
650
651    /* Populate the target slot. */
652    if (mbedtls_svc_key_id_equal(target_id, source_id)) {
653        returned_target_id = returned_source_id;
654    } else {
655        psa_set_key_id(&attributes1, target_id);
656        psa_set_key_lifetime(&attributes1, target_lifetime);
657        psa_set_key_type(&attributes1, target_type);
658        psa_set_key_usage_flags(&attributes1, target_usage);
659        psa_set_key_algorithm(&attributes1, target_alg);
660        PSA_ASSERT(psa_import_key(&attributes1,
661                                  target_material->x, target_material->len,
662                                  &returned_target_id));
663    }
664
665    PSA_ASSERT(psa_get_key_attributes(returned_target_id, &attributes1));
666
667    /* Make a copy attempt. */
668    psa_set_key_id(&attributes, target_id);
669    psa_set_key_lifetime(&attributes, target_lifetime);
670    TEST_EQUAL(psa_copy_key(returned_source_id,
671                            &attributes, &new_key),
672               PSA_ERROR_ALREADY_EXISTS);
673    TEST_ASSERT(mbedtls_svc_key_id_is_null(new_key));
674
675    /* Test that the target slot is unaffected. */
676    PSA_ASSERT(psa_get_key_attributes(returned_target_id, &attributes2));
677    TEST_ASSERT(mbedtls_svc_key_id_equal(
678                    psa_get_key_id(&attributes1),
679                    psa_get_key_id(&attributes2)));
680    TEST_EQUAL(psa_get_key_lifetime(&attributes1),
681               psa_get_key_lifetime(&attributes2));
682    TEST_EQUAL(psa_get_key_type(&attributes1),
683               psa_get_key_type(&attributes2));
684    TEST_EQUAL(psa_get_key_bits(&attributes1),
685               psa_get_key_bits(&attributes2));
686    TEST_EQUAL(psa_get_key_usage_flags(&attributes1),
687               psa_get_key_usage_flags(&attributes2));
688    TEST_EQUAL(psa_get_key_algorithm(&attributes1),
689               psa_get_key_algorithm(&attributes2));
690    if (target_usage & PSA_KEY_USAGE_EXPORT) {
691        size_t length;
692        ASSERT_ALLOC(export_buffer, target_material->len);
693        PSA_ASSERT(psa_export_key(returned_target_id, export_buffer,
694                                  target_material->len, &length));
695        ASSERT_COMPARE(target_material->x, target_material->len,
696                       export_buffer, length);
697    }
698
699    PSA_ASSERT(psa_destroy_key(returned_source_id));
700    if (!mbedtls_svc_key_id_equal(target_id, source_id)) {
701        PSA_ASSERT(psa_destroy_key(returned_target_id));
702    }
703
704exit:
705    /*
706     * Key attributes may have been returned by psa_get_key_attributes()
707     * thus reset them as required.
708     */
709    psa_reset_key_attributes(&attributes1);
710    psa_reset_key_attributes(&attributes2);
711
712    PSA_DONE();
713    mbedtls_free(export_buffer);
714}
715/* END_CASE */
716
717/* BEGIN_CASE */
718void invalid_handle(int handle_construction,
719                    int close_status_arg)
720{
721    psa_key_handle_t valid_handle = PSA_KEY_HANDLE_INIT;
722    psa_key_handle_t invalid_handle = PSA_KEY_HANDLE_INIT;
723    psa_key_id_t key_id;
724    psa_status_t close_status = close_status_arg;
725    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
726    uint8_t material[1] = "a";
727
728    PSA_ASSERT(psa_crypto_init());
729
730    /* Allocate a handle and store a key in it. */
731    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
732    psa_set_key_usage_flags(&attributes, 0);
733    psa_set_key_algorithm(&attributes, 0);
734    PSA_ASSERT(psa_import_key(&attributes,
735                              material, sizeof(material),
736                              &valid_handle));
737    TEST_ASSERT(!psa_key_handle_is_null(valid_handle));
738
739    /* Construct an invalid handle as specified in the test case data. */
740    switch (handle_construction) {
741        case INVALID_HANDLE_0:
742            invalid_handle = PSA_KEY_HANDLE_INIT;
743            break;
744        case INVALID_HANDLE_UNOPENED:
745
746            /*
747             * MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile
748             * key identifier as the imported key is a volatile key. Volatile
749             * key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN
750             * to PSA_KEY_ID_VOLATILE_MAX included. Thus pick a key identifier
751             * in the range from PSA_KEY_ID_VOLATILE_MIN to
752             * PSA_KEY_ID_VOLATILE_MAX different from
753             * MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) to build an
754             * unopened and thus invalid identifier.
755             */
756
757            if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(valid_handle) ==
758                PSA_KEY_ID_VOLATILE_MIN) {
759                key_id = PSA_KEY_ID_VOLATILE_MIN + 1;
760            } else {
761                key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(valid_handle) - 1;
762            }
763
764            invalid_handle =
765                mbedtls_svc_key_id_make(0, key_id);
766            break;
767        case INVALID_HANDLE_CLOSED:
768            PSA_ASSERT(psa_import_key(&attributes,
769                                      material, sizeof(material),
770                                      &invalid_handle));
771            PSA_ASSERT(psa_destroy_key(invalid_handle));
772            break;
773        case INVALID_HANDLE_HUGE:
774            invalid_handle =
775                mbedtls_svc_key_id_make(0, PSA_KEY_ID_VENDOR_MAX + 1);
776            break;
777        default:
778            TEST_ASSERT(!"unknown handle construction");
779    }
780
781    /* Attempt to use the invalid handle. */
782    TEST_EQUAL(psa_get_key_attributes(invalid_handle, &attributes),
783               PSA_ERROR_INVALID_HANDLE);
784    TEST_EQUAL(psa_close_key(invalid_handle), close_status);
785    TEST_EQUAL(psa_destroy_key(invalid_handle), close_status);
786
787    /* After all this, check that the original handle is intact. */
788    PSA_ASSERT(psa_get_key_attributes(valid_handle, &attributes));
789    TEST_EQUAL(psa_get_key_type(&attributes), PSA_KEY_TYPE_RAW_DATA);
790    TEST_EQUAL(psa_get_key_bits(&attributes),
791               PSA_BYTES_TO_BITS(sizeof(material)));
792    PSA_ASSERT(psa_close_key(valid_handle));
793
794exit:
795    /*
796     * Key attributes may have been returned by psa_get_key_attributes()
797     * thus reset them as required.
798     */
799    psa_reset_key_attributes(&attributes);
800
801    PSA_DONE();
802}
803/* END_CASE */
804
805/* BEGIN_CASE */
806void many_transient_keys(int max_keys_arg)
807{
808    mbedtls_svc_key_id_t *keys = NULL;
809    size_t max_keys = max_keys_arg;
810    size_t i, j;
811    psa_status_t status;
812    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
813    uint8_t exported[sizeof(size_t)];
814    size_t exported_length;
815
816    ASSERT_ALLOC(keys, max_keys);
817    PSA_ASSERT(psa_crypto_init());
818
819    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
820    psa_set_key_algorithm(&attributes, 0);
821    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
822
823    for (i = 0; i < max_keys; i++) {
824        status = psa_import_key(&attributes,
825                                (uint8_t *) &i, sizeof(i),
826                                &keys[i]);
827        if (status == PSA_ERROR_INSUFFICIENT_MEMORY) {
828            break;
829        }
830        PSA_ASSERT(status);
831        TEST_ASSERT(!mbedtls_svc_key_id_is_null(keys[i]));
832        for (j = 0; j < i; j++) {
833            TEST_ASSERT(!mbedtls_svc_key_id_equal(keys[i], keys[j]));
834        }
835    }
836    max_keys = i;
837
838    for (i = 1; i < max_keys; i++) {
839        PSA_ASSERT(psa_close_key(keys[i - 1]));
840        PSA_ASSERT(psa_export_key(keys[i],
841                                  exported, sizeof(exported),
842                                  &exported_length));
843        ASSERT_COMPARE(exported, exported_length,
844                       (uint8_t *) &i, sizeof(i));
845    }
846    PSA_ASSERT(psa_close_key(keys[i - 1]));
847
848exit:
849    PSA_DONE();
850    mbedtls_free(keys);
851}
852/* END_CASE */
853
854/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
855void key_slot_eviction_to_import_new_key(int lifetime_arg)
856{
857    psa_key_lifetime_t lifetime = (psa_key_lifetime_t) lifetime_arg;
858    size_t i;
859    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
860    uint8_t exported[sizeof(size_t)];
861    size_t exported_length;
862    mbedtls_svc_key_id_t key, returned_key_id;
863
864    PSA_ASSERT(psa_crypto_init());
865
866    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
867    psa_set_key_algorithm(&attributes, 0);
868    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
869
870    /*
871     * Create MBEDTLS_PSA_KEY_SLOT_COUNT persistent keys.
872     */
873    for (i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
874        key = mbedtls_svc_key_id_make(i, i + 1);
875        psa_set_key_id(&attributes, key);
876        PSA_ASSERT(psa_import_key(&attributes,
877                                  (uint8_t *) &i, sizeof(i),
878                                  &returned_key_id));
879        TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key));
880    }
881
882    /*
883     * Create a new persistent or volatile key. When creating the key,
884     * one of the descriptions of the previously created persistent keys
885     * is removed from the RAM key slots. This makes room to store its
886     * description in RAM.
887     */
888    i = MBEDTLS_PSA_KEY_SLOT_COUNT;
889    key = mbedtls_svc_key_id_make(i, i + 1);
890    psa_set_key_id(&attributes, key);
891    psa_set_key_lifetime(&attributes, lifetime);
892
893    PSA_ASSERT(psa_import_key(&attributes,
894                              (uint8_t *) &i, sizeof(i),
895                              &returned_key_id));
896    if (lifetime != PSA_KEY_LIFETIME_VOLATILE) {
897        TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key));
898    } else {
899        TEST_ASSERT(psa_key_id_is_volatile(
900                        MBEDTLS_SVC_KEY_ID_GET_KEY_ID(returned_key_id)));
901    }
902
903    /*
904     * Check that we can export all ( MBEDTLS_PSA_KEY_SLOT_COUNT + 1 ) keys,
905     * that they have the expected value and destroy them. In that process,
906     * the description of the persistent key that was evicted from the RAM
907     * slots when creating the last key is restored in a RAM slot to export
908     * its value.
909     */
910    for (i = 0; i <= MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
911        if (i < MBEDTLS_PSA_KEY_SLOT_COUNT) {
912            key = mbedtls_svc_key_id_make(i, i + 1);
913        } else {
914            key = returned_key_id;
915        }
916
917        PSA_ASSERT(psa_export_key(key,
918                                  exported, sizeof(exported),
919                                  &exported_length));
920        ASSERT_COMPARE(exported, exported_length,
921                       (uint8_t *) &i, sizeof(i));
922        PSA_ASSERT(psa_destroy_key(key));
923    }
924
925exit:
926    PSA_DONE();
927}
928/* END_CASE */
929
930/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */
931void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
932{
933    psa_status_t status;
934    size_t i;
935    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
936    uint8_t exported[sizeof(size_t)];
937    size_t exported_length;
938    mbedtls_svc_key_id_t persistent_key = MBEDTLS_SVC_KEY_ID_INIT;
939    mbedtls_svc_key_id_t persistent_key2 = MBEDTLS_SVC_KEY_ID_INIT;
940    mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
941    mbedtls_svc_key_id_t *keys = NULL;
942
943    TEST_ASSERT(MBEDTLS_PSA_KEY_SLOT_COUNT >= 1);
944
945    ASSERT_ALLOC(keys, MBEDTLS_PSA_KEY_SLOT_COUNT);
946    PSA_ASSERT(psa_crypto_init());
947
948    psa_set_key_usage_flags(&attributes,
949                            PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY);
950    psa_set_key_algorithm(&attributes, 0);
951    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
952
953    /*
954     * Create a persistent key
955     */
956    persistent_key = mbedtls_svc_key_id_make(0x100, 0x205);
957    psa_set_key_id(&attributes, persistent_key);
958    PSA_ASSERT(psa_import_key(&attributes,
959                              (uint8_t *) &persistent_key,
960                              sizeof(persistent_key),
961                              &returned_key_id));
962    TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, persistent_key));
963
964    /*
965     * Create MBEDTLS_PSA_KEY_SLOT_COUNT volatile keys
966     */
967    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
968    for (i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
969        PSA_ASSERT(psa_import_key(&attributes,
970                                  (uint8_t *) &i, sizeof(i),
971                                  &keys[i]));
972    }
973    psa_reset_key_attributes(&attributes);
974
975    /*
976     * Check that we cannot access the persistent key as all slots are
977     * occupied by volatile keys and the implementation needs to load the
978     * persistent key description in a slot to be able to access it.
979     */
980    status = psa_get_key_attributes(persistent_key, &attributes);
981    TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
982
983    /*
984     * Check we can export the volatile key created last and that it has the
985     * expected value. Then, destroy it.
986     */
987    PSA_ASSERT(psa_export_key(keys[MBEDTLS_PSA_KEY_SLOT_COUNT - 1],
988                              exported, sizeof(exported),
989                              &exported_length));
990    i = MBEDTLS_PSA_KEY_SLOT_COUNT - 1;
991    ASSERT_COMPARE(exported, exported_length, (uint8_t *) &i, sizeof(i));
992    PSA_ASSERT(psa_destroy_key(keys[MBEDTLS_PSA_KEY_SLOT_COUNT - 1]));
993
994    /*
995     * Check that we can now access the persistent key again.
996     */
997    PSA_ASSERT(psa_get_key_attributes(persistent_key, &attributes));
998    TEST_ASSERT(mbedtls_svc_key_id_equal(attributes.core.id,
999                                         persistent_key));
1000
1001    /*
1002     * Check that we cannot copy the persistent key as all slots are occupied
1003     * by the persistent key and the volatile keys and the slot containing the
1004     * persistent key cannot be reclaimed as it contains the key to copy.
1005     */
1006    persistent_key2 = mbedtls_svc_key_id_make(0x100, 0x204);
1007    psa_set_key_id(&attributes, persistent_key2);
1008    status = psa_copy_key(persistent_key, &attributes, &returned_key_id);
1009    TEST_EQUAL(status, PSA_ERROR_INSUFFICIENT_MEMORY);
1010
1011    /*
1012     * Check we can export the remaining volatile keys and that they have the
1013     * expected values.
1014     */
1015    for (i = 0; i < (MBEDTLS_PSA_KEY_SLOT_COUNT - 1); i++) {
1016        PSA_ASSERT(psa_export_key(keys[i],
1017                                  exported, sizeof(exported),
1018                                  &exported_length));
1019        ASSERT_COMPARE(exported, exported_length,
1020                       (uint8_t *) &i, sizeof(i));
1021        PSA_ASSERT(psa_destroy_key(keys[i]));
1022    }
1023
1024    /*
1025     * Check we can export the persistent key and that it have the expected
1026     * value.
1027     */
1028
1029    PSA_ASSERT(psa_export_key(persistent_key, exported, sizeof(exported),
1030                              &exported_length));
1031    ASSERT_COMPARE(exported, exported_length,
1032                   (uint8_t *) &persistent_key, sizeof(persistent_key));
1033exit:
1034    /*
1035     * Key attributes may have been returned by psa_get_key_attributes()
1036     * thus reset them as required.
1037     */
1038    psa_reset_key_attributes(&attributes);
1039
1040    psa_destroy_key(persistent_key);
1041    PSA_DONE();
1042    mbedtls_free(keys);
1043}
1044/* END_CASE */
1045