| /* BEGIN_HEADER */ |
| #include "psa_crypto_helpers.h" |
| #include "psa/crypto_se_driver.h" |
| |
| #include "psa_crypto_se.h" |
| #include "psa_crypto_storage.h" |
| |
| |
| |
| /****************************************************************/ |
| /* Test driver helpers */ |
| /****************************************************************/ |
| |
| /** The minimum valid lifetime value for a secure element driver. */ |
| #define MIN_DRIVER_LIFETIME 2 |
| |
| /** The driver detected a condition that shouldn't happen. |
| * This is probably a bug in the library. */ |
| #define PSA_ERROR_DETECTED_BY_DRIVER ((psa_status_t)( -500 )) |
| |
| /** Like #TEST_ASSERT for use in a driver method. |
| * |
| * Use this macro to assert on guarantees provided by the core. |
| */ |
| #define DRIVER_ASSERT( TEST ) \ |
| do { \ |
| if( ! (TEST) ) \ |
| { \ |
| test_fail( #TEST, __LINE__, __FILE__ ); \ |
| return( PSA_ERROR_DETECTED_BY_DRIVER ); \ |
| } \ |
| } while( 0 ) |
| |
| |
| |
| /****************************************************************/ |
| /* Miscellaneous driver methods */ |
| /****************************************************************/ |
| |
| /* Allocate slot numbers with a monotonic counter. */ |
| static psa_status_t counter_allocate( psa_drv_se_context_t *context, |
| void *persistent_data, |
| const psa_key_attributes_t *attributes, |
| psa_key_slot_number_t *slot_number ) |
| { |
| psa_key_slot_number_t *p_counter = persistent_data; |
| (void) attributes; |
| if( context->persistent_data_size != sizeof( psa_key_slot_number_t ) ) |
| return( PSA_ERROR_DETECTED_BY_DRIVER ); |
| ++*p_counter; |
| if( *p_counter == 0 ) |
| return( PSA_ERROR_INSUFFICIENT_STORAGE ); |
| *slot_number = *p_counter; |
| return( PSA_SUCCESS ); |
| } |
| |
| /* Null import: do nothing, but pretend it worked. */ |
| static psa_status_t null_import( psa_drv_se_context_t *context, |
| psa_key_slot_number_t slot_number, |
| psa_key_lifetime_t lifetime, |
| psa_key_type_t type, |
| psa_algorithm_t algorithm, |
| psa_key_usage_t usage, |
| const uint8_t *p_data, |
| size_t data_length, |
| size_t *bits ) |
| { |
| (void) context; |
| (void) slot_number; |
| (void) lifetime; |
| (void) type; |
| (void) algorithm; |
| (void) usage; |
| (void) p_data; |
| /* We're supposed to return a key size. Return one that's correct for |
| * plain data keys. */ |
| *bits = PSA_BYTES_TO_BITS( data_length ); |
| return( PSA_SUCCESS ); |
| } |
| |
| |
| |
| /****************************************************************/ |
| /* RAM-based test driver */ |
| /****************************************************************/ |
| |
| #define RAM_MAX_KEY_SIZE 64 |
| typedef struct |
| { |
| psa_key_lifetime_t lifetime; |
| psa_key_type_t type; |
| size_t bits; |
| uint8_t content[RAM_MAX_KEY_SIZE]; |
| } ram_slot_t; |
| static ram_slot_t ram_slots[16]; |
| |
| /* A type with at least ARRAY_LENGTH(ram_slots) bits, containing a |
| * bit vector indicating which slots are in use. */ |
| typedef uint16_t ram_slot_usage_t; |
| |
| static uint8_t ram_min_slot = 0; |
| |
| static void ram_slots_reset( void ) |
| { |
| memset( ram_slots, 0, sizeof( ram_slots ) ); |
| ram_min_slot = 0; |
| } |
| |
| static psa_status_t ram_import( psa_drv_se_context_t *context, |
| psa_key_slot_number_t slot_number, |
| psa_key_lifetime_t lifetime, |
| psa_key_type_t type, |
| psa_algorithm_t algorithm, |
| psa_key_usage_t usage, |
| const uint8_t *p_data, |
| size_t data_length, |
| size_t *bits ) |
| { |
| (void) context; |
| DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) ); |
| if( data_length > sizeof( ram_slots[slot_number].content ) ) |
| return( PSA_ERROR_INSUFFICIENT_STORAGE ); |
| ram_slots[slot_number].lifetime = lifetime; |
| ram_slots[slot_number].type = type; |
| ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length ); |
| *bits = PSA_BYTES_TO_BITS( data_length ); |
| (void) algorithm; |
| (void) usage; |
| memcpy( ram_slots[slot_number].content, p_data, data_length ); |
| return( PSA_SUCCESS ); |
| } |
| |
| static psa_status_t ram_export( psa_drv_se_context_t *context, |
| psa_key_slot_number_t slot_number, |
| uint8_t *p_data, |
| size_t data_size, |
| size_t *p_data_length ) |
| { |
| size_t actual_size; |
| (void) context; |
| DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) ); |
| actual_size = PSA_BITS_TO_BYTES( ram_slots[slot_number].bits ); |
| if( actual_size > data_size ) |
| return( PSA_ERROR_BUFFER_TOO_SMALL ); |
| *p_data_length = actual_size; |
| memcpy( p_data, ram_slots[slot_number].content, actual_size ); |
| return( PSA_SUCCESS ); |
| } |
| |
| static psa_status_t ram_destroy( psa_drv_se_context_t *context, |
| void *persistent_data, |
| psa_key_slot_number_t slot_number ) |
| { |
| ram_slot_usage_t *slot_usage = persistent_data; |
| DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) ); |
| DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) ); |
| memset( &ram_slots[slot_number], 0, sizeof( ram_slots[slot_number] ) ); |
| *slot_usage &= ~(ram_slot_usage_t)( 1 << slot_number ); |
| return( PSA_SUCCESS ); |
| } |
| |
| static psa_status_t ram_allocate( psa_drv_se_context_t *context, |
| void *persistent_data, |
| const psa_key_attributes_t *attributes, |
| psa_key_slot_number_t *slot_number ) |
| { |
| ram_slot_usage_t *slot_usage = persistent_data; |
| (void) attributes; |
| DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) ); |
| for( *slot_number = ram_min_slot; |
| *slot_number < ARRAY_LENGTH( ram_slots ); |
| ++( *slot_number ) ) |
| { |
| if( ! ( *slot_usage & 1 << *slot_number ) ) |
| return( PSA_SUCCESS ); |
| } |
| return( PSA_ERROR_INSUFFICIENT_STORAGE ); |
| } |
| |
| |
| |
| /****************************************************************/ |
| /* Other test helper functions */ |
| /****************************************************************/ |
| |
| /* Check that the attributes of a key reported by psa_get_key_attributes() |
| * are consistent with the attributes used when creating the key. */ |
| static int check_key_attributes( |
| psa_key_handle_t handle, |
| const psa_key_attributes_t *reference_attributes ) |
| { |
| int ok = 0; |
| psa_key_attributes_t actual_attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| PSA_ASSERT( psa_get_key_attributes( handle, &actual_attributes ) ); |
| |
| TEST_EQUAL( psa_get_key_id( &actual_attributes ), |
| psa_get_key_id( reference_attributes ) ); |
| TEST_EQUAL( psa_get_key_lifetime( &actual_attributes ), |
| psa_get_key_lifetime( reference_attributes ) ); |
| TEST_EQUAL( psa_get_key_type( &actual_attributes ), |
| psa_get_key_type( reference_attributes ) ); |
| TEST_EQUAL( psa_get_key_usage_flags( &actual_attributes ), |
| psa_get_key_usage_flags( reference_attributes ) ); |
| TEST_EQUAL( psa_get_key_algorithm( &actual_attributes ), |
| psa_get_key_algorithm( reference_attributes ) ); |
| TEST_EQUAL( psa_get_key_enrollment_algorithm( &actual_attributes ), |
| psa_get_key_enrollment_algorithm( reference_attributes ) ); |
| if( psa_get_key_bits( reference_attributes ) != 0 ) |
| { |
| TEST_EQUAL( psa_get_key_bits( &actual_attributes ), |
| psa_get_key_bits( reference_attributes ) ); |
| } |
| |
| { |
| psa_key_slot_number_t actual_slot_number = 0xdeadbeef; |
| psa_key_slot_number_t desired_slot_number = 0xb90cc011; |
| psa_key_lifetime_t lifetime = |
| psa_get_key_lifetime( &actual_attributes ); |
| psa_status_t status = psa_get_key_slot_number( &actual_attributes, |
| &actual_slot_number ); |
| if( lifetime < MIN_DRIVER_LIFETIME ) |
| { |
| /* The key is not in a secure element. */ |
| TEST_EQUAL( status, PSA_ERROR_INVALID_ARGUMENT ); |
| } |
| else |
| { |
| /* The key is in a secure element. If it had been created |
| * in a specific slot, check that it is reported there. */ |
| PSA_ASSERT( status ); |
| status = psa_get_key_slot_number( reference_attributes, |
| &desired_slot_number ); |
| if( status == PSA_SUCCESS ) |
| { |
| TEST_EQUAL( desired_slot_number, actual_slot_number ); |
| } |
| } |
| } |
| ok = 1; |
| |
| exit: |
| return( ok ); |
| } |
| |
| /* Check that a function's return status is "smoke-free", i.e. that |
| * it's an acceptable error code when calling an API function that operates |
| * on a key with potentially bogus parameters. */ |
| static int is_status_smoke_free( psa_status_t status ) |
| { |
| switch( status ) |
| { |
| case PSA_SUCCESS: |
| case PSA_ERROR_NOT_SUPPORTED: |
| case PSA_ERROR_NOT_PERMITTED: |
| case PSA_ERROR_BUFFER_TOO_SMALL: |
| case PSA_ERROR_INVALID_ARGUMENT: |
| case PSA_ERROR_INVALID_SIGNATURE: |
| case PSA_ERROR_INVALID_PADDING: |
| return( 1 ); |
| default: |
| return( 0 ); |
| } |
| } |
| #define SMOKE_ASSERT( expr ) \ |
| TEST_ASSERT( is_status_smoke_free( expr ) ) |
| |
| /* Smoke test a key. There are mostly no wrong answers here since we pass |
| * mostly bogus parameters: the goal is to ensure that there is no memory |
| * corruption or crash. This test function is most useful when run under |
| * an environment with sanity checks such as ASan or MSan. */ |
| static int smoke_test_key( psa_key_handle_t handle ) |
| { |
| int ok = 0; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT; |
| psa_cipher_operation_t cipher_operation = PSA_CIPHER_OPERATION_INIT; |
| psa_key_derivation_operation_t derivation_operation = |
| PSA_KEY_DERIVATION_OPERATION_INIT; |
| uint8_t buffer[80]; /* large enough for a public key for ECDH */ |
| size_t length; |
| psa_key_handle_t handle2 = 0; |
| |
| SMOKE_ASSERT( psa_get_key_attributes( handle, &attributes ) ); |
| |
| SMOKE_ASSERT( psa_export_key( handle, |
| buffer, sizeof( buffer ), &length ) ); |
| SMOKE_ASSERT( psa_export_public_key( handle, |
| buffer, sizeof( buffer ), &length ) ); |
| |
| SMOKE_ASSERT( psa_copy_key( handle, &attributes, &handle2 ) ); |
| if( handle2 != 0 ) |
| PSA_ASSERT( psa_close_key( handle2 ) ); |
| |
| SMOKE_ASSERT( psa_mac_sign_setup( &mac_operation, handle, PSA_ALG_CMAC ) ); |
| PSA_ASSERT( psa_mac_abort( &mac_operation ) ); |
| SMOKE_ASSERT( psa_mac_verify_setup( &mac_operation, handle, |
| PSA_ALG_HMAC( PSA_ALG_SHA_256 ) ) ); |
| PSA_ASSERT( psa_mac_abort( &mac_operation ) ); |
| |
| SMOKE_ASSERT( psa_cipher_encrypt_setup( &cipher_operation, handle, |
| PSA_ALG_CTR ) ); |
| PSA_ASSERT( psa_cipher_abort( &cipher_operation ) ); |
| SMOKE_ASSERT( psa_cipher_decrypt_setup( &cipher_operation, handle, |
| PSA_ALG_CTR ) ); |
| PSA_ASSERT( psa_cipher_abort( &cipher_operation ) ); |
| |
| SMOKE_ASSERT( psa_aead_encrypt( handle, PSA_ALG_CCM, |
| buffer, sizeof( buffer ), |
| NULL, 0, |
| buffer, sizeof( buffer), |
| buffer, sizeof( buffer), &length ) ); |
| SMOKE_ASSERT( psa_aead_decrypt( handle, PSA_ALG_CCM, |
| buffer, sizeof( buffer ), |
| NULL, 0, |
| buffer, sizeof( buffer), |
| buffer, sizeof( buffer), &length ) ); |
| |
| SMOKE_ASSERT( psa_asymmetric_sign( handle, PSA_ALG_ECDSA_ANY, |
| buffer, 32, |
| buffer, sizeof( buffer ), &length ) ); |
| SMOKE_ASSERT( psa_asymmetric_verify( handle, PSA_ALG_ECDSA_ANY, |
| buffer, 32, |
| buffer, sizeof( buffer ) ) ); |
| |
| SMOKE_ASSERT( psa_asymmetric_encrypt( handle, PSA_ALG_RSA_PKCS1V15_CRYPT, |
| buffer, 10, NULL, 0, |
| buffer, sizeof( buffer ), &length ) ); |
| SMOKE_ASSERT( psa_asymmetric_decrypt( handle, PSA_ALG_RSA_PKCS1V15_CRYPT, |
| buffer, sizeof( buffer ), NULL, 0, |
| buffer, sizeof( buffer ), &length ) ); |
| |
| #if defined(MBEDTLS_SHA256_C) |
| /* Try the key in a plain key derivation. */ |
| PSA_ASSERT( psa_key_derivation_setup( &derivation_operation, |
| PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ) ); |
| PSA_ASSERT( psa_key_derivation_input_bytes( &derivation_operation, |
| PSA_KEY_DERIVATION_INPUT_SALT, |
| NULL, 0 ) ); |
| SMOKE_ASSERT( psa_key_derivation_input_key( &derivation_operation, |
| PSA_KEY_DERIVATION_INPUT_SECRET, |
| handle ) ); |
| PSA_ASSERT( psa_key_derivation_abort( &derivation_operation ) ); |
| |
| /* If the key is asymmetric, try it in a key agreement, both as |
| * part of a derivation operation and standalone. */ |
| if( psa_export_public_key( handle, buffer, sizeof( buffer ), &length ) == |
| PSA_SUCCESS ) |
| { |
| psa_algorithm_t alg = |
| PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, |
| PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ); |
| PSA_ASSERT( psa_key_derivation_setup( &derivation_operation, alg ) ); |
| PSA_ASSERT( psa_key_derivation_input_bytes( |
| &derivation_operation, PSA_KEY_DERIVATION_INPUT_SALT, |
| NULL, 0 ) ); |
| SMOKE_ASSERT( psa_key_derivation_key_agreement( |
| &derivation_operation, |
| PSA_KEY_DERIVATION_INPUT_SECRET, |
| handle, buffer, length ) ); |
| PSA_ASSERT( psa_key_derivation_abort( &derivation_operation ) ); |
| |
| SMOKE_ASSERT( psa_raw_key_agreement( |
| alg, handle, buffer, length, |
| buffer, sizeof( buffer ), &length ) ); |
| } |
| #endif /* MBEDTLS_SHA256_C */ |
| |
| ok = 1; |
| |
| exit: |
| psa_reset_key_attributes( &attributes ); |
| return( ok ); |
| } |
| |
| #define MAX_KEY_ID_FOR_TEST 10 |
| static void psa_purge_storage( void ) |
| { |
| psa_key_id_t id; |
| psa_key_lifetime_t lifetime; |
| /* The tests may have potentially created key ids from 1 to |
| * MAX_KEY_ID_FOR_TEST. In addition, run the destroy function on key id |
| * 0, which file-based storage uses as a temporary file. */ |
| for( id = 0; id <= MAX_KEY_ID_FOR_TEST; id++ ) |
| psa_destroy_persistent_key( id ); |
| /* Purge the transaction file. */ |
| psa_crypto_stop_transaction( ); |
| /* Purge driver persistent data. */ |
| for( lifetime = 0; lifetime < PSA_MAX_SE_LIFETIME; lifetime++ ) |
| psa_destroy_se_persistent_data( lifetime ); |
| } |
| |
| /* END_HEADER */ |
| |
| /* BEGIN_DEPENDENCIES |
| * depends_on:MBEDTLS_PSA_CRYPTO_SE_C |
| * END_DEPENDENCIES |
| */ |
| |
| /* BEGIN_CASE */ |
| void register_one( int lifetime, int version, int expected_status_arg ) |
| { |
| psa_status_t expected_status = expected_status_arg; |
| psa_drv_se_t driver; |
| |
| memset( &driver, 0, sizeof( driver ) ); |
| driver.hal_version = version; |
| |
| TEST_EQUAL( psa_register_se_driver( lifetime, &driver ), |
| expected_status ); |
| |
| PSA_ASSERT( psa_crypto_init( ) ); |
| |
| exit: |
| PSA_DONE( ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void register_twice( int count ) |
| { |
| psa_drv_se_t driver; |
| psa_key_lifetime_t lifetime; |
| psa_key_lifetime_t max = MIN_DRIVER_LIFETIME + count; |
| |
| memset( &driver, 0, sizeof( driver ) ); |
| driver.hal_version = PSA_DRV_SE_HAL_VERSION; |
| |
| for( lifetime = MIN_DRIVER_LIFETIME; lifetime < max; lifetime++ ) |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| for( lifetime = MIN_DRIVER_LIFETIME; lifetime < max; lifetime++ ) |
| TEST_EQUAL( psa_register_se_driver( lifetime, &driver ), |
| PSA_ERROR_ALREADY_EXISTS ); |
| |
| PSA_ASSERT( psa_crypto_init( ) ); |
| |
| exit: |
| PSA_DONE( ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void register_max( ) |
| { |
| psa_drv_se_t driver; |
| psa_key_lifetime_t lifetime; |
| psa_key_lifetime_t max = MIN_DRIVER_LIFETIME + PSA_MAX_SE_DRIVERS; |
| |
| memset( &driver, 0, sizeof( driver ) ); |
| driver.hal_version = PSA_DRV_SE_HAL_VERSION; |
| |
| for( lifetime = MIN_DRIVER_LIFETIME; lifetime < max; lifetime++ ) |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| |
| TEST_EQUAL( psa_register_se_driver( lifetime, &driver ), |
| PSA_ERROR_INSUFFICIENT_MEMORY ); |
| |
| PSA_ASSERT( psa_crypto_init( ) ); |
| |
| exit: |
| PSA_DONE( ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void key_creation_import_export( int min_slot, int restart ) |
| { |
| psa_drv_se_t driver; |
| psa_drv_se_key_management_t key_management; |
| psa_key_lifetime_t lifetime = 2; |
| psa_key_id_t id = 1; |
| psa_key_handle_t handle = 0; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| const uint8_t key_material[3] = {0xfa, 0xca, 0xde}; |
| uint8_t exported[sizeof( key_material )]; |
| size_t exported_length; |
| |
| memset( &driver, 0, sizeof( driver ) ); |
| memset( &key_management, 0, sizeof( key_management ) ); |
| driver.hal_version = PSA_DRV_SE_HAL_VERSION; |
| driver.key_management = &key_management; |
| driver.persistent_data_size = sizeof( ram_slot_usage_t ); |
| key_management.p_allocate = ram_allocate; |
| key_management.p_import = ram_import; |
| key_management.p_destroy = ram_destroy; |
| key_management.p_export = ram_export; |
| ram_min_slot = min_slot; |
| |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| PSA_ASSERT( psa_crypto_init( ) ); |
| |
| /* Create a key. */ |
| psa_set_key_id( &attributes, id ); |
| psa_set_key_lifetime( &attributes, lifetime ); |
| psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT ); |
| psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA ); |
| PSA_ASSERT( psa_import_key( &attributes, |
| key_material, sizeof( key_material ), |
| &handle ) ); |
| |
| /* Maybe restart, to check that the information is saved correctly. */ |
| if( restart ) |
| { |
| mbedtls_psa_crypto_free( ); |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| PSA_ASSERT( psa_crypto_init( ) ); |
| PSA_ASSERT( psa_open_key( id, &handle ) ); |
| } |
| |
| /* Test that the key was created in the expected slot. */ |
| TEST_ASSERT( ram_slots[min_slot].type == PSA_KEY_TYPE_RAW_DATA ); |
| |
| /* Test the key attributes, including the reported slot number. */ |
| psa_set_key_bits( &attributes, |
| PSA_BYTES_TO_BITS( sizeof( key_material ) ) ); |
| psa_set_key_slot_number( &attributes, min_slot ); |
| if( ! check_key_attributes( handle, &attributes ) ) |
| goto exit; |
| |
| /* Test the key data. */ |
| PSA_ASSERT( psa_export_key( handle, |
| exported, sizeof( exported ), |
| &exported_length ) ); |
| ASSERT_COMPARE( key_material, sizeof( key_material ), |
| exported, exported_length ); |
| |
| PSA_ASSERT( psa_destroy_key( handle ) ); |
| |
| /* Test that the key has been erased from the designated slot. */ |
| TEST_ASSERT( ram_slots[min_slot].type == 0 ); |
| |
| exit: |
| PSA_DONE( ); |
| ram_slots_reset( ); |
| psa_purge_storage( ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void key_creation_smoke( int type_arg, int alg_arg, |
| data_t *key_material ) |
| { |
| psa_key_type_t type = type_arg; |
| psa_algorithm_t alg = alg_arg; |
| psa_drv_se_t driver; |
| psa_drv_se_key_management_t key_management; |
| psa_key_lifetime_t lifetime = 2; |
| psa_key_id_t id = 1; |
| psa_key_handle_t handle = 0; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| memset( &driver, 0, sizeof( driver ) ); |
| memset( &key_management, 0, sizeof( key_management ) ); |
| driver.hal_version = PSA_DRV_SE_HAL_VERSION; |
| driver.key_management = &key_management; |
| driver.persistent_data_size = sizeof( psa_key_slot_number_t ); |
| key_management.p_allocate = counter_allocate; |
| key_management.p_import = null_import; |
| |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| PSA_ASSERT( psa_crypto_init( ) ); |
| |
| /* Create a key. */ |
| psa_set_key_id( &attributes, id ); |
| psa_set_key_lifetime( &attributes, lifetime ); |
| psa_set_key_usage_flags( &attributes, |
| PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY | |
| PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | |
| PSA_KEY_USAGE_EXPORT ); |
| psa_set_key_algorithm( &attributes, alg ); |
| psa_set_key_type( &attributes, type ); |
| PSA_ASSERT( psa_import_key( &attributes, |
| key_material->x, key_material->len, |
| &handle ) ); |
| |
| /* Do stuff with the key. */ |
| if( ! smoke_test_key( handle ) ) |
| goto exit; |
| |
| /* Restart and try again. */ |
| mbedtls_psa_crypto_free( ); |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| PSA_ASSERT( psa_crypto_init( ) ); |
| PSA_ASSERT( psa_open_key( id, &handle ) ); |
| if( ! smoke_test_key( handle ) ) |
| goto exit; |
| |
| /* We're done. */ |
| PSA_ASSERT( psa_destroy_key( handle ) ); |
| |
| exit: |
| PSA_DONE( ); |
| ram_slots_reset( ); |
| psa_purge_storage( ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void generate_key_not_supported( int type_arg, int bits_arg ) |
| { |
| psa_key_type_t type = type_arg; |
| size_t bits = bits_arg; |
| psa_drv_se_t driver; |
| psa_drv_se_key_management_t key_management; |
| psa_key_lifetime_t lifetime = 2; |
| psa_key_id_t id = 1; |
| psa_key_handle_t handle = 0; |
| psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| |
| memset( &driver, 0, sizeof( driver ) ); |
| memset( &key_management, 0, sizeof( key_management ) ); |
| driver.hal_version = PSA_DRV_SE_HAL_VERSION; |
| driver.key_management = &key_management; |
| driver.persistent_data_size = sizeof( psa_key_slot_number_t ); |
| key_management.p_allocate = counter_allocate; |
| |
| PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) ); |
| PSA_ASSERT( psa_crypto_init( ) ); |
| |
| psa_set_key_id( &attributes, id ); |
| psa_set_key_lifetime( &attributes, lifetime ); |
| psa_set_key_type( &attributes, type ); |
| psa_set_key_bits( &attributes, bits ); |
| TEST_EQUAL( psa_generate_key( &attributes, &handle ), |
| PSA_ERROR_NOT_SUPPORTED ); |
| |
| exit: |
| PSA_DONE( ); |
| ram_slots_reset( ); |
| psa_purge_storage( ); |
| } |
| /* END_CASE */ |