1/* BEGIN_HEADER */
2
3/* The tests in this module verify the contents of key store files. They
4 * access internal key storage functions directly. Some of the tests depend
5 * on the storage format. On the other hand, these tests treat the storage
6 * subsystem as a black box, and in particular have no reliance on the
7 * internals of the ITS implementation.
8 *
9 * Note that if you need to make a change that affects how files are
10 * stored, this may indicate that the key store is changing in a
11 * backward-incompatible way! Think carefully about backward compatibility
12 * before changing how test data is constructed or validated.
13 */
14
15#include <stdint.h>
16
17#include "psa_crypto_slot_management.h"
18#include "psa_crypto_storage.h"
19
20#include "mbedtls/md.h"
21
22#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
23#define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER))
24
25/* Enforce the storage format for keys. The storage format is not a public
26 * documented interface, but it must be preserved between versions so that
27 * upgrades work smoothly, so it's a stable interface nonetheless.
28 */
29typedef struct {
30    uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
31    uint8_t version[4];
32    uint8_t lifetime[sizeof(psa_key_lifetime_t)];
33    uint8_t type[4];
34    uint8_t policy[sizeof(psa_key_policy_t)];
35    uint8_t data_len[4];
36    uint8_t key_data[];
37} psa_persistent_key_storage_format;
38
39/* END_HEADER */
40
41/* BEGIN_DEPENDENCIES
42 * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_C
43 * END_DEPENDENCIES
44 */
45
46/* BEGIN_CASE */
47void format_storage_data_check(data_t *key_data,
48                               data_t *expected_file_data,
49                               int key_lifetime, int key_type, int key_bits,
50                               int key_usage, int key_alg, int key_alg2)
51{
52    uint8_t *file_data = NULL;
53    size_t file_data_length =
54        key_data->len + sizeof(psa_persistent_key_storage_format);
55    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
56
57    psa_set_key_lifetime(&attributes, key_lifetime);
58    psa_set_key_type(&attributes, key_type);
59    psa_set_key_bits(&attributes, key_bits);
60    psa_set_key_usage_flags(&attributes, key_usage);
61    psa_set_key_algorithm(&attributes, key_alg);
62    psa_set_key_enrollment_algorithm(&attributes, key_alg2);
63
64    TEST_CALLOC(file_data, file_data_length);
65    psa_format_key_data_for_storage(key_data->x, key_data->len,
66                                    &attributes.core,
67                                    file_data);
68
69    TEST_MEMORY_COMPARE(expected_file_data->x, expected_file_data->len,
70                        file_data, file_data_length);
71
72exit:
73    mbedtls_free(file_data);
74}
75/* END_CASE */
76
77/* BEGIN_CASE */
78void parse_storage_data_check(data_t *file_data,
79                              data_t *expected_key_data,
80                              int expected_key_lifetime,
81                              int expected_key_type,
82                              int expected_key_bits,
83                              int expected_key_usage,
84                              int expected_key_alg,
85                              int expected_key_alg2,
86                              int expected_status)
87{
88    uint8_t *key_data = NULL;
89    size_t key_data_length = 0;
90    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
91    psa_status_t status;
92
93    status = psa_parse_key_data_from_storage(file_data->x, file_data->len,
94                                             &key_data, &key_data_length,
95                                             &attributes.core);
96
97    TEST_EQUAL(status, expected_status);
98    if (status != PSA_SUCCESS) {
99        goto exit;
100    }
101
102    TEST_EQUAL(psa_get_key_lifetime(&attributes),
103               (psa_key_type_t) expected_key_lifetime);
104    TEST_EQUAL(psa_get_key_type(&attributes),
105               (psa_key_type_t) expected_key_type);
106    TEST_EQUAL(psa_get_key_bits(&attributes),
107               (psa_key_bits_t) expected_key_bits);
108    TEST_EQUAL(psa_get_key_usage_flags(&attributes),
109               (uint32_t) expected_key_usage);
110    TEST_EQUAL(psa_get_key_algorithm(&attributes),
111               (uint32_t) expected_key_alg);
112    TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes),
113               (uint32_t) expected_key_alg2);
114    TEST_MEMORY_COMPARE(expected_key_data->x, expected_key_data->len,
115                        key_data, key_data_length);
116
117exit:
118    mbedtls_free(key_data);
119}
120/* END_CASE */
121
122/* BEGIN_CASE */
123void save_large_persistent_key(int data_length_arg, int expected_status)
124{
125    mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 42);
126    uint8_t *data = NULL;
127    size_t data_length = data_length_arg;
128    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
129
130    TEST_CALLOC(data, data_length);
131
132    PSA_ASSERT(psa_crypto_init());
133
134    psa_set_key_id(&attributes, key_id);
135    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
136
137    TEST_EQUAL(psa_import_key(&attributes, data, data_length, &key_id),
138               expected_status);
139
140    if (expected_status == PSA_SUCCESS) {
141        PSA_ASSERT(psa_destroy_key(key_id));
142    }
143
144exit:
145    mbedtls_free(data);
146    PSA_DONE();
147    psa_destroy_persistent_key(key_id);
148}
149/* END_CASE */
150
151/* BEGIN_CASE */
152void persistent_key_destroy(int owner_id_arg, int key_id_arg, int restart,
153                            int first_type_arg, data_t *first_data,
154                            int second_type_arg, data_t *second_data)
155{
156    mbedtls_svc_key_id_t key_id =
157        mbedtls_svc_key_id_make(owner_id_arg, key_id_arg);
158    mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
159    psa_key_type_t first_type = (psa_key_type_t) first_type_arg;
160    psa_key_type_t second_type = (psa_key_type_t) second_type_arg;
161    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
162
163    PSA_ASSERT(psa_crypto_init());
164
165    psa_set_key_id(&attributes, key_id);
166    psa_set_key_type(&attributes, first_type);
167
168    PSA_ASSERT(psa_import_key(&attributes, first_data->x, first_data->len,
169                              &returned_key_id));
170
171    if (restart) {
172        psa_close_key(key_id);
173        PSA_DONE();
174        PSA_ASSERT(psa_crypto_init());
175    }
176    TEST_EQUAL(psa_is_key_present_in_storage(key_id), 1);
177
178    /* Destroy the key */
179    PSA_ASSERT(psa_destroy_key(key_id));
180
181    /* Check key slot storage is removed */
182    TEST_EQUAL(psa_is_key_present_in_storage(key_id), 0);
183
184    /* Shutdown and restart */
185    PSA_DONE();
186    PSA_ASSERT(psa_crypto_init());
187
188    /* Create another key in the same slot */
189    psa_set_key_id(&attributes, key_id);
190    psa_set_key_type(&attributes, second_type);
191    PSA_ASSERT(psa_import_key(&attributes, second_data->x, second_data->len,
192                              &returned_key_id));
193
194    PSA_ASSERT(psa_destroy_key(key_id));
195
196exit:
197    PSA_DONE();
198    psa_destroy_persistent_key(key_id);
199}
200/* END_CASE */
201
202/* BEGIN_CASE */
203void persistent_key_import(int owner_id_arg, int key_id_arg, int type_arg,
204                           data_t *data, int restart, int expected_status)
205{
206    mbedtls_svc_key_id_t key_id =
207        mbedtls_svc_key_id_make(owner_id_arg, key_id_arg);
208    mbedtls_svc_key_id_t returned_key_id;
209    psa_key_type_t type = (psa_key_type_t) type_arg;
210    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
211
212    PSA_ASSERT(psa_crypto_init());
213
214    psa_set_key_id(&attributes, key_id);
215    psa_set_key_type(&attributes, type);
216    TEST_EQUAL(psa_import_key(&attributes, data->x, data->len, &returned_key_id),
217               expected_status);
218
219    if (expected_status != PSA_SUCCESS) {
220        TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_key_id));
221        TEST_EQUAL(psa_is_key_present_in_storage(key_id), 0);
222        goto exit;
223    }
224
225    TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key_id));
226
227    if (restart) {
228        PSA_ASSERT(psa_purge_key(key_id));
229        PSA_DONE();
230        PSA_ASSERT(psa_crypto_init());
231    }
232
233    psa_reset_key_attributes(&attributes);
234    PSA_ASSERT(psa_get_key_attributes(key_id, &attributes));
235    TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(&attributes),
236                                         key_id));
237    TEST_EQUAL(psa_get_key_lifetime(&attributes),
238               PSA_KEY_LIFETIME_PERSISTENT);
239    TEST_EQUAL(psa_get_key_type(&attributes), type);
240    TEST_EQUAL(psa_get_key_usage_flags(&attributes), 0);
241    TEST_EQUAL(psa_get_key_algorithm(&attributes), 0);
242
243    PSA_ASSERT(psa_destroy_key(key_id));
244
245exit:
246    /*
247     * Key attributes may have been returned by psa_get_key_attributes()
248     * thus reset them as required.
249     */
250    psa_reset_key_attributes(&attributes);
251
252    psa_destroy_persistent_key(key_id);
253    PSA_DONE();
254}
255/* END_CASE */
256
257/* BEGIN_CASE */
258void import_export_persistent_key(data_t *data, int type_arg,
259                                  int expected_bits,
260                                  int restart, int key_not_exist)
261{
262    mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 42);
263    psa_key_type_t type = (psa_key_type_t) type_arg;
264    mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
265    unsigned char *exported = NULL;
266    size_t export_size = data->len;
267    size_t exported_length;
268    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
269
270    TEST_CALLOC(exported, export_size);
271
272    PSA_ASSERT(psa_crypto_init());
273
274    psa_set_key_id(&attributes, key_id);
275    psa_set_key_type(&attributes, type);
276    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
277
278    /* Import the key */
279    PSA_ASSERT(psa_import_key(&attributes, data->x, data->len,
280                              &returned_key_id));
281
282
283    if (restart) {
284        PSA_ASSERT(psa_purge_key(key_id));
285        PSA_DONE();
286        PSA_ASSERT(psa_crypto_init());
287    }
288
289    /* Test the key information */
290    psa_reset_key_attributes(&attributes);
291    PSA_ASSERT(psa_get_key_attributes(key_id, &attributes));
292    TEST_ASSERT(mbedtls_svc_key_id_equal(
293                    psa_get_key_id(&attributes), key_id));
294    TEST_EQUAL(psa_get_key_lifetime(&attributes),
295               PSA_KEY_LIFETIME_PERSISTENT);
296    TEST_EQUAL(psa_get_key_type(&attributes), type);
297    TEST_EQUAL(psa_get_key_bits(&attributes), (size_t) expected_bits);
298    TEST_EQUAL(psa_get_key_usage_flags(&attributes), PSA_KEY_USAGE_EXPORT);
299    TEST_EQUAL(psa_get_key_algorithm(&attributes), 0);
300
301    TEST_EQUAL(psa_is_key_present_in_storage(key_id), 1);
302
303    if (key_not_exist) {
304        psa_destroy_persistent_key(key_id);
305    }
306    /* Export the key */
307    PSA_ASSERT(psa_export_key(key_id, exported, export_size,
308                              &exported_length));
309
310    TEST_MEMORY_COMPARE(data->x, data->len, exported, exported_length);
311
312    /* Destroy the key */
313    PSA_ASSERT(psa_destroy_key(key_id));
314    TEST_EQUAL(psa_is_key_present_in_storage(key_id), 0);
315
316exit:
317    /*
318     * Key attributes may have been returned by psa_get_key_attributes()
319     * thus reset them as required.
320     */
321    psa_reset_key_attributes(&attributes);
322
323    mbedtls_free(exported);
324    PSA_DONE();
325    psa_destroy_persistent_key(key_id);
326}
327/* END_CASE */
328
329/* BEGIN_CASE */
330void destroy_nonexistent(int id_arg, int expected_status_arg)
331{
332    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg);
333    psa_status_t expected_status = expected_status_arg;
334
335    PSA_INIT();
336
337    TEST_EQUAL(expected_status, psa_destroy_key(id));
338
339exit:
340    PSA_DONE();
341}
342/* END_CASE */
343