| /* BEGIN_HEADER */ |
| |
| /* The tests in this module verify the contents of key store files. They |
| * access internal key storage functions directly. Some of the tests depend |
| * on the storage format. On the other hand, these tests treat the storage |
| * subsystem as a black box, and in particular have no reliance on the |
| * internals of the ITS implementation. |
| * |
| * Note that if you need to make a change that affects how files are |
| * stored, this may indicate that the key store is changing in a |
| * backward-incompatible way! Think carefully about backward compatibility |
| * before changing how test data is constructed or validated. |
| */ |
| |
| #include <stdint.h> |
| |
| #include "psa_crypto_slot_management.h" |
| #include "psa_crypto_storage.h" |
| |
| #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" |
| #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH (sizeof(PSA_KEY_STORAGE_MAGIC_HEADER)) |
| |
| /* Enforce the storage format for keys. The storage format is not a public |
| * documented interface, but it must be preserved between versions so that |
| * upgrades work smoothly, so it's a stable interface nonetheless. |
| */ |
| typedef struct { |
| uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH]; |
| uint8_t version[4]; |
| uint8_t lifetime[sizeof(psa_key_lifetime_t)]; |
| uint8_t type[4]; |
| uint8_t policy[sizeof(psa_key_policy_t)]; |
| uint8_t data_len[4]; |
| uint8_t key_data[]; |
| } psa_persistent_key_storage_format; |
| |
| /* END_HEADER */ |
| |
| /* BEGIN_DEPENDENCIES |
| * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_PSA_CRYPTO_STORAGE_C |
| * END_DEPENDENCIES |
| */ |
| |
| /* BEGIN_CASE */ |
| void format_storage_data_check(data_t *key_data, |
| data_t *expected_file_data, |
| int key_lifetime, int key_type, int key_bits, |
| int key_usage, int key_alg, int key_alg2) |
| { |
| uint8_t *file_data = NULL; |
| size_t file_data_length = |
| key_data->len + sizeof(psa_persistent_key_storage_format); |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| psa_set_key_lifetime(&attributes, key_lifetime); |
| psa_set_key_type(&attributes, key_type); |
| psa_set_key_bits(&attributes, key_bits); |
| psa_set_key_usage_flags(&attributes, key_usage); |
| psa_set_key_algorithm(&attributes, key_alg); |
| psa_set_key_enrollment_algorithm(&attributes, key_alg2); |
| |
| TEST_CALLOC(file_data, file_data_length); |
| psa_format_key_data_for_storage(key_data->x, key_data->len, |
| &attributes, |
| file_data); |
| |
| TEST_MEMORY_COMPARE(expected_file_data->x, expected_file_data->len, |
| file_data, file_data_length); |
| |
| exit: |
| mbedtls_free(file_data); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void parse_storage_data_check(data_t *file_data, |
| data_t *expected_key_data, |
| int expected_key_lifetime, |
| int expected_key_type, |
| int expected_key_bits, |
| int expected_key_usage, |
| int expected_key_alg, |
| int expected_key_alg2, |
| int expected_status) |
| { |
| uint8_t *key_data = NULL; |
| size_t key_data_length = 0; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| psa_status_t status; |
| |
| status = psa_parse_key_data_from_storage(file_data->x, file_data->len, |
| &key_data, &key_data_length, |
| &attributes); |
| |
| TEST_EQUAL(status, expected_status); |
| if (status != PSA_SUCCESS) { |
| goto exit; |
| } |
| |
| TEST_EQUAL(psa_get_key_lifetime(&attributes), |
| (psa_key_type_t) expected_key_lifetime); |
| TEST_EQUAL(psa_get_key_type(&attributes), |
| (psa_key_type_t) expected_key_type); |
| TEST_EQUAL(psa_get_key_bits(&attributes), |
| (psa_key_bits_t) expected_key_bits); |
| TEST_EQUAL(psa_get_key_usage_flags(&attributes), |
| (uint32_t) expected_key_usage); |
| TEST_EQUAL(psa_get_key_algorithm(&attributes), |
| (uint32_t) expected_key_alg); |
| TEST_EQUAL(psa_get_key_enrollment_algorithm(&attributes), |
| (uint32_t) expected_key_alg2); |
| TEST_MEMORY_COMPARE(expected_key_data->x, expected_key_data->len, |
| key_data, key_data_length); |
| |
| exit: |
| mbedtls_free(key_data); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void save_large_persistent_key(int data_length_arg, int expected_status) |
| { |
| mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 42); |
| uint8_t *data = NULL; |
| size_t data_length = data_length_arg; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| TEST_CALLOC(data, data_length); |
| |
| PSA_ASSERT(psa_crypto_init()); |
| |
| psa_set_key_id(&attributes, key_id); |
| psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA); |
| |
| TEST_EQUAL(psa_import_key(&attributes, data, data_length, &key_id), |
| expected_status); |
| |
| if (expected_status == PSA_SUCCESS) { |
| PSA_ASSERT(psa_destroy_key(key_id)); |
| } |
| |
| exit: |
| mbedtls_free(data); |
| PSA_DONE(); |
| psa_destroy_persistent_key(key_id); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void persistent_key_destroy(int owner_id_arg, int key_id_arg, int restart, |
| int first_type_arg, data_t *first_data, |
| int second_type_arg, data_t *second_data) |
| { |
| mbedtls_svc_key_id_t key_id = |
| mbedtls_svc_key_id_make(owner_id_arg, key_id_arg); |
| mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT; |
| psa_key_type_t first_type = (psa_key_type_t) first_type_arg; |
| psa_key_type_t second_type = (psa_key_type_t) second_type_arg; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| PSA_ASSERT(psa_crypto_init()); |
| |
| psa_set_key_id(&attributes, key_id); |
| psa_set_key_type(&attributes, first_type); |
| |
| PSA_ASSERT(psa_import_key(&attributes, first_data->x, first_data->len, |
| &returned_key_id)); |
| |
| if (restart) { |
| psa_close_key(key_id); |
| PSA_DONE(); |
| PSA_ASSERT(psa_crypto_init()); |
| } |
| TEST_EQUAL(psa_is_key_present_in_storage(key_id), 1); |
| |
| /* Destroy the key */ |
| PSA_ASSERT(psa_destroy_key(key_id)); |
| |
| /* Check key slot storage is removed */ |
| TEST_EQUAL(psa_is_key_present_in_storage(key_id), 0); |
| |
| /* Shutdown and restart */ |
| PSA_DONE(); |
| PSA_ASSERT(psa_crypto_init()); |
| |
| /* Create another key in the same slot */ |
| psa_set_key_id(&attributes, key_id); |
| psa_set_key_type(&attributes, second_type); |
| PSA_ASSERT(psa_import_key(&attributes, second_data->x, second_data->len, |
| &returned_key_id)); |
| |
| PSA_ASSERT(psa_destroy_key(key_id)); |
| |
| exit: |
| PSA_DONE(); |
| psa_destroy_persistent_key(key_id); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void persistent_key_import(int owner_id_arg, int key_id_arg, int type_arg, |
| data_t *data, int restart, int expected_status) |
| { |
| mbedtls_svc_key_id_t key_id = |
| mbedtls_svc_key_id_make(owner_id_arg, key_id_arg); |
| mbedtls_svc_key_id_t returned_key_id; |
| psa_key_type_t type = (psa_key_type_t) type_arg; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| PSA_ASSERT(psa_crypto_init()); |
| |
| psa_set_key_id(&attributes, key_id); |
| psa_set_key_type(&attributes, type); |
| TEST_EQUAL(psa_import_key(&attributes, data->x, data->len, &returned_key_id), |
| expected_status); |
| |
| if (expected_status != PSA_SUCCESS) { |
| TEST_ASSERT(mbedtls_svc_key_id_is_null(returned_key_id)); |
| TEST_EQUAL(psa_is_key_present_in_storage(key_id), 0); |
| goto exit; |
| } |
| |
| TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, key_id)); |
| |
| if (restart) { |
| PSA_ASSERT(psa_purge_key(key_id)); |
| PSA_DONE(); |
| PSA_ASSERT(psa_crypto_init()); |
| } |
| |
| psa_reset_key_attributes(&attributes); |
| PSA_ASSERT(psa_get_key_attributes(key_id, &attributes)); |
| TEST_ASSERT(mbedtls_svc_key_id_equal(psa_get_key_id(&attributes), |
| key_id)); |
| TEST_EQUAL(psa_get_key_lifetime(&attributes), |
| PSA_KEY_LIFETIME_PERSISTENT); |
| TEST_EQUAL(psa_get_key_type(&attributes), type); |
| TEST_EQUAL(psa_get_key_usage_flags(&attributes), 0); |
| TEST_EQUAL(psa_get_key_algorithm(&attributes), 0); |
| |
| PSA_ASSERT(psa_destroy_key(key_id)); |
| |
| exit: |
| /* |
| * Key attributes may have been returned by psa_get_key_attributes() |
| * thus reset them as required. |
| */ |
| psa_reset_key_attributes(&attributes); |
| |
| psa_destroy_persistent_key(key_id); |
| PSA_DONE(); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void import_export_persistent_key(data_t *data, int type_arg, |
| int expected_bits, |
| int restart, int key_not_exist) |
| { |
| mbedtls_svc_key_id_t key_id = mbedtls_svc_key_id_make(1, 42); |
| psa_key_type_t type = (psa_key_type_t) type_arg; |
| mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT; |
| unsigned char *exported = NULL; |
| size_t export_size = data->len; |
| size_t exported_length; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| TEST_CALLOC(exported, export_size); |
| |
| PSA_ASSERT(psa_crypto_init()); |
| |
| psa_set_key_id(&attributes, key_id); |
| psa_set_key_type(&attributes, type); |
| psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT); |
| |
| /* Import the key */ |
| PSA_ASSERT(psa_import_key(&attributes, data->x, data->len, |
| &returned_key_id)); |
| |
| |
| if (restart) { |
| PSA_ASSERT(psa_purge_key(key_id)); |
| PSA_DONE(); |
| PSA_ASSERT(psa_crypto_init()); |
| } |
| |
| /* Test the key information */ |
| psa_reset_key_attributes(&attributes); |
| PSA_ASSERT(psa_get_key_attributes(key_id, &attributes)); |
| TEST_ASSERT(mbedtls_svc_key_id_equal( |
| psa_get_key_id(&attributes), key_id)); |
| TEST_EQUAL(psa_get_key_lifetime(&attributes), |
| PSA_KEY_LIFETIME_PERSISTENT); |
| TEST_EQUAL(psa_get_key_type(&attributes), type); |
| TEST_EQUAL(psa_get_key_bits(&attributes), (size_t) expected_bits); |
| TEST_EQUAL(psa_get_key_usage_flags(&attributes), PSA_KEY_USAGE_EXPORT); |
| TEST_EQUAL(psa_get_key_algorithm(&attributes), 0); |
| |
| TEST_EQUAL(psa_is_key_present_in_storage(key_id), 1); |
| |
| if (key_not_exist) { |
| psa_destroy_persistent_key(key_id); |
| } |
| /* Export the key */ |
| PSA_ASSERT(psa_export_key(key_id, exported, export_size, |
| &exported_length)); |
| |
| TEST_MEMORY_COMPARE(data->x, data->len, exported, exported_length); |
| |
| /* Destroy the key */ |
| PSA_ASSERT(psa_destroy_key(key_id)); |
| TEST_EQUAL(psa_is_key_present_in_storage(key_id), 0); |
| |
| exit: |
| /* |
| * Key attributes may have been returned by psa_get_key_attributes() |
| * thus reset them as required. |
| */ |
| psa_reset_key_attributes(&attributes); |
| |
| mbedtls_free(exported); |
| PSA_DONE(); |
| psa_destroy_persistent_key(key_id); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void destroy_nonexistent(int id_arg, int expected_status_arg) |
| { |
| mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, id_arg); |
| psa_status_t expected_status = expected_status_arg; |
| |
| PSA_INIT(); |
| |
| TEST_EQUAL(expected_status, psa_destroy_key(id)); |
| |
| exit: |
| PSA_DONE(); |
| } |
| /* END_CASE */ |