/* BEGIN_HEADER */ #include #include "psa/crypto.h" #include "psa_crypto_storage.h" #include "psa_crypto_storage_backend.h" #include "mbedtls/md.h" #define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY" #define PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ( sizeof( PSA_KEY_STORAGE_MAGIC_HEADER ) ) typedef struct { uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH]; uint8_t version[4]; uint8_t type[sizeof( psa_key_type_t )]; 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_type, int key_usage, int key_alg ) { uint8_t *file_data; size_t file_data_length; psa_key_policy_t key_policy; key_policy.usage = (psa_key_usage_t) key_usage; key_policy.alg = (psa_algorithm_t) key_alg; file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format ); file_data = mbedtls_calloc( 1, file_data_length ); psa_format_key_data_for_storage( key_data->x, key_data->len, (psa_key_type_t) key_type, &key_policy, file_data ); ASSERT_COMPARE( expected_file_data->x, expected_file_data->len, file_data, file_data_length ); 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_type, int expected_key_usage, int expected_key_alg, int expected_status ) { uint8_t *key_data = NULL; size_t key_data_length = 0; psa_key_type_t key_type = 0; psa_key_policy_t key_policy; psa_status_t status; status = psa_parse_key_data_from_storage( file_data->x, file_data->len, &key_data, &key_data_length, &key_type, &key_policy ); TEST_ASSERT( status == expected_status ); if( status != PSA_SUCCESS ) goto exit; TEST_ASSERT( key_type == (psa_key_type_t) expected_key_type ); TEST_ASSERT( key_policy.usage == (uint32_t) expected_key_usage ); TEST_ASSERT( key_policy.alg == (uint32_t) expected_key_alg ); ASSERT_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_too_large, int expected_status ) { psa_key_slot_t slot = 1; uint8_t *data = NULL; size_t data_length = PSA_CRYPTO_MAX_STORAGE_SIZE; if( data_too_large ) data_length += 1; ASSERT_ALLOC( data, data_length ); TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); TEST_ASSERT( psa_set_key_lifetime( slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_RAW_DATA, data, data_length ) == expected_status ); exit: mbedtls_free( data ); psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); } /* END_CASE */ /* BEGIN_CASE */ void persistent_key_is_configurable( int slot_arg, int type_arg, data_t *data ) { psa_key_policy_t policy; psa_key_lifetime_t lifetime; psa_key_slot_t slot = (psa_key_slot_t) slot_arg; psa_key_type_t type = (psa_key_type_t) type_arg; TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); TEST_ASSERT( psa_set_key_lifetime( slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); TEST_ASSERT( psa_import_key( slot, type, data->x, data->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS ); TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT ); exit: psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); } /* END_CASE */ /* BEGIN_CASE */ void persistent_key_destroy( int slot_arg, int should_store, int first_type_arg, data_t *first_data, int second_type_arg, data_t *second_data ) { psa_key_policy_t policy; psa_key_slot_t slot = (psa_key_slot_t) slot_arg; 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; TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); TEST_ASSERT( psa_set_key_lifetime( slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); if( should_store == 1 ) { TEST_ASSERT( psa_import_key( slot, first_type, first_data->x, first_data->len ) == PSA_SUCCESS ); } /* Destroy the key */ TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_information( slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); /* Check key slot storage is removed */ TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); /* Check destroying the key again doesn't report failure */ TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_information( slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); /* Shutdown and restart */ mbedtls_psa_crypto_free(); TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); /* Mark slot as persistent again */ TEST_ASSERT( psa_set_key_lifetime( slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); /* Check key slot is empty */ TEST_ASSERT( psa_get_key_information( slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); /* Import different key data to ensure slot really was empty */ psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_VENDOR_FLAG ); TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); TEST_ASSERT( psa_import_key( slot, second_type, second_data->x, second_data->len ) == PSA_SUCCESS ); exit: psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); } /* END_CASE */ /* BEGIN_CASE */ void default_volatile_lifetime( int slot_arg, int type_arg, data_t *data ) { psa_key_policy_t policy; psa_key_slot_t slot = (psa_key_slot_t) slot_arg; psa_key_type_t type = (psa_key_type_t) type_arg; TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); psa_key_policy_init( &policy ); TEST_ASSERT( psa_import_key( slot, type, data->x, data->len ) == PSA_SUCCESS ); /* Shutdown and restart */ mbedtls_psa_crypto_free(); TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); /* Check key slot is empty */ TEST_ASSERT( psa_get_key_information( slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); exit: psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); } /* END_CASE */ /* BEGIN_CASE */ void persistent_key_import( int slot_arg, int type_arg, data_t *data, int expected_status ) { psa_key_policy_t policy; psa_key_lifetime_t lifetime; psa_key_slot_t slot = (psa_key_slot_t) slot_arg; psa_key_type_t type = (psa_key_type_t) type_arg; TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); TEST_ASSERT( psa_set_key_lifetime( slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); TEST_ASSERT( psa_import_key( slot, type, data->x, data->len ) == expected_status ); if( expected_status != PSA_SUCCESS ) { TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); goto exit; } TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS ); TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT ); exit: psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); } /* END_CASE */ /* BEGIN_CASE */ void import_export_persistent_key( data_t *data, int type_arg, int expected_bits, int key_not_exist ) { psa_key_slot_t slot = 1; psa_key_type_t type = (psa_key_type_t) type_arg; unsigned char *exported = NULL; size_t export_size = data->len; size_t exported_length; psa_key_type_t got_type; size_t got_bits; psa_key_policy_t policy; psa_key_lifetime_t lifetime_get; ASSERT_ALLOC( exported, export_size ); TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); TEST_ASSERT( psa_set_key_lifetime( slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_VENDOR_FLAG ); TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); /* Import the key */ TEST_ASSERT( psa_import_key( slot, type, data->x, data->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime_get ) == PSA_SUCCESS ); TEST_ASSERT( lifetime_get == PSA_KEY_LIFETIME_PERSISTENT ); /* Test the key information */ TEST_ASSERT( psa_get_key_information( slot, &got_type, &got_bits ) == PSA_SUCCESS ); TEST_ASSERT( got_type == type ); TEST_ASSERT( got_bits == (size_t) expected_bits ); TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 1 ); if( key_not_exist ) { psa_destroy_persistent_key( slot ); } /* Export the key */ TEST_ASSERT( psa_export_key( slot, exported, export_size, &exported_length ) == PSA_SUCCESS ); ASSERT_COMPARE( data->x, data->len, exported, exported_length ); /* Destroy the key */ TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_information( slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); exit: mbedtls_free( exported ); psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free( ); } /* END_CASE */