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