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