diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 90158f852..e26a7ec01 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5687,6 +5687,12 @@ psa_status_t psa_crypto_init( void ) if( status != PSA_SUCCESS ) goto exit; +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) + status = psa_init_all_se_drivers( ); + if( status != PSA_SUCCESS ) + goto exit; +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) status = psa_crypto_load_transaction( ); if( status == PSA_SUCCESS ) diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c index 81b310367..81f0a1a8f 100644 --- a/library/psa_crypto_se.c +++ b/library/psa_crypto_se.c @@ -272,6 +272,28 @@ psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver, return( status == PSA_SUCCESS ? storage_status : status ); } +psa_status_t psa_init_all_se_drivers( void ) +{ + size_t i; + for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ ) + { + psa_se_drv_table_entry_t *driver = &driver_table[i]; + if( driver->lifetime == 0 ) + continue; /* skipping unused entry */ + const psa_drv_se_t *methods = psa_get_se_driver_methods( driver ); + if( methods->p_init != NULL ) + { + psa_status_t status = methods->p_init( + &driver->context, + driver->internal.persistent_data, + driver->lifetime ); + if( status != PSA_SUCCESS ) + return( status ); + } + } + return( PSA_SUCCESS ); +} + /****************************************************************/ diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h index 900a72bd3..86bf7a7b1 100644 --- a/library/psa_crypto_se.h +++ b/library/psa_crypto_se.h @@ -66,6 +66,12 @@ */ void psa_unregister_all_se_drivers( void ); +/** Initialize all secure element drivers. + * + * Called from psa_crypto_init(). + */ +psa_status_t psa_init_all_se_drivers( void ); + /** A structure that describes a registered secure element driver. * * A secure element driver table entry contains a pointer to the diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data index dba68758f..f60bd7602 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.data @@ -1,3 +1,12 @@ +SE init mock test: success +mock_init:2:PSA_SUCCESS:PSA_SUCCESS:PSA_SUCCESS:1 + +SE init mock test: failure +mock_init:2:PSA_SUCCESS:PSA_ERROR_HARDWARE_FAILURE:PSA_ERROR_HARDWARE_FAILURE:1 + +SE init mock test: invalid lifetime +mock_init:1:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_BAD_STATE:PSA_SUCCESS:0 + SE key importing mock test mock_import:PSA_SUCCESS:PSA_SUCCESS:0:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function index e6b3f7b1f..7088a5226 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal_mocks.function @@ -5,6 +5,13 @@ #include "psa_crypto_se.h" #include "psa_crypto_storage.h" +static struct +{ + uint16_t called; + psa_key_lifetime_t lifetime; + psa_status_t return_value; +} mock_init_data; + static struct { uint16_t called; @@ -92,6 +99,7 @@ static void psa_purge_storage( void ) static void mock_teardown( void ) { + memset( &mock_init_data, 0, sizeof( mock_init_data ) ); memset( &mock_import_data, 0, sizeof( mock_import_data ) ); memset( &mock_export_data, 0, sizeof( mock_export_data ) ); memset( &mock_export_public_data, 0, sizeof( mock_export_public_data ) ); @@ -103,6 +111,18 @@ static void mock_teardown( void ) psa_purge_storage( ); } +static psa_status_t mock_init( psa_drv_se_context_t *drv_context, + void *persistent_data, + psa_key_lifetime_t lifetime ) +{ + (void) drv_context; + (void) persistent_data; + + mock_init_data.called++; + mock_init_data.lifetime = lifetime; + return( mock_init_data.return_value ); +} + static psa_status_t mock_generate( psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, const psa_key_attributes_t *attributes, @@ -258,6 +278,42 @@ psa_status_t mock_destroy( psa_drv_se_context_t *context, * END_DEPENDENCIES */ +/* BEGIN_CASE */ +void mock_init( int lifetime_arg, + int expected_register_status_arg, + int driver_status_arg, + int expected_psa_status_arg, + int expected_called ) +{ + psa_key_lifetime_t lifetime = lifetime_arg; + psa_status_t expected_register_status = expected_register_status_arg; + psa_status_t driver_status = driver_status_arg; + psa_status_t expected_psa_status = expected_psa_status_arg; + psa_drv_se_t driver = { + .hal_version = PSA_DRV_SE_HAL_VERSION, + .p_init = mock_init, + }; + int psa_crypto_init_called = 0; + + mock_init_data.return_value = driver_status; + + TEST_EQUAL( psa_register_se_driver( lifetime, &driver ), + expected_register_status ); + + psa_crypto_init_called = 1; + TEST_EQUAL( psa_crypto_init( ), expected_psa_status ); + + TEST_EQUAL( mock_init_data.called, expected_called ); + if( expected_called ) + TEST_EQUAL( mock_init_data.lifetime, lifetime ); + +exit: + if( psa_crypto_init_called ) + PSA_DONE( ); + mock_teardown( ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mock_import( int mock_alloc_return_value, int mock_import_return_value, @@ -335,6 +391,7 @@ void mock_export( int mock_export_return_value, int expected_result ) memset( &key_management, 0, sizeof( key_management ) ); driver.hal_version = PSA_DRV_SE_HAL_VERSION; driver.key_management = &key_management; + driver.p_init = mock_init; key_management.p_import = mock_import; key_management.p_export = mock_export; key_management.p_destroy = mock_destroy;