Test shutdown without closing handles

Add some test cases that shut down and restart without explicitly
closing handles, and check that the handles are properly invalidated.
This commit is contained in:
Gilles Peskine 2019-05-28 15:06:43 +02:00
parent 76b29a77fb
commit dd413d3c92
3 changed files with 111 additions and 35 deletions

View File

@ -32,7 +32,7 @@
*/ */
#define PSA_ASSERT( expr ) TEST_EQUAL( ( expr ), PSA_SUCCESS ) #define PSA_ASSERT( expr ) TEST_EQUAL( ( expr ), PSA_SUCCESS )
static void test_helper_psa_done( int line, const char *file ) static int test_helper_is_psa_pristine( int line, const char *file )
{ {
mbedtls_psa_stats_t stats; mbedtls_psa_stats_t stats;
const char *msg = NULL; const char *msg = NULL;
@ -48,12 +48,28 @@ static void test_helper_psa_done( int line, const char *file )
else if( stats.half_filled_slots != 0 ) else if( stats.half_filled_slots != 0 )
msg = "A half-filled slot has not been cleared properly."; msg = "A half-filled slot has not been cleared properly.";
/* If the test failed, don't overwrite the failure information. /* If the test has already failed, don't overwrite the failure
* Do keep the stats lookup above, because it can be convenient to * information. Do keep the stats lookup above, because it can be
* break on it when debugging a failure. */ * convenient to break on it when debugging a failure. */
if( msg != NULL && test_info.failed == 0 ) if( msg != NULL && test_info.failed == 0 )
test_fail( msg, line, file ); test_fail( msg, line, file );
return( msg == NULL );
}
/** Check that no PSA slots are in use.
*/
#define ASSERT_PSA_PRISTINE( ) \
do \
{ \
if( ! test_helper_is_psa_pristine( __LINE__, __FILE__ ) ) \
goto exit; \
} \
while( 0 )
static void test_helper_psa_done( int line, const char *file )
{
(void) test_helper_is_psa_pristine( line, file );
mbedtls_psa_crypto_free( ); mbedtls_psa_crypto_free( );
} }

View File

@ -1,19 +1,31 @@
Transient slot, check after closing Transient slot, check after closing
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
Transient slot, check after closing and restarting
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE_WITH_SHUTDOWN
Transient slot, check after destroying Transient slot, check after destroying
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
Transient slot, check after restart Transient slot, check after destroying and restarting
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY_WITH_SHUTDOWN
Transient slot, check after restart with live handles
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN
Persistent slot, check after closing, id=min Persistent slot, check after closing, id=min
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
Persistent slot, check after closing and restarting, id=min
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
Persistent slot, check after destroying, id=min Persistent slot, check after destroying, id=min
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
Persistent slot, check after restart, id=min Persistent slot, check after destroying and restarting, id=min
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
Persistent slot, check after restart with live handle, id=min
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN
Persistent slot, check after closing, id=max Persistent slot, check after closing, id=max
@ -29,6 +41,10 @@ Persistent slot: ECP keypair (ECDSA, exportable); close
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE
Persistent slot: ECP keypair (ECDSA, exportable); close+restart
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE_WITH_SHUTDOWN
Persistent slot: ECP keypair (ECDSA, exportable); restart Persistent slot: ECP keypair (ECDSA, exportable); restart
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN
@ -37,6 +53,10 @@ Persistent slot: ECP keypair (ECDH+ECDSA, exportable); close
depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE
Persistent slot: ECP keypair (ECDH+ECDSA, exportable); close+restart
depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE_WITH_SHUTDOWN
Persistent slot: ECP keypair (ECDH+ECDSA, exportable); restart Persistent slot: ECP keypair (ECDH+ECDSA, exportable); restart
depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN

View File

@ -6,9 +6,11 @@
typedef enum typedef enum
{ {
CLOSE_BY_CLOSE, CLOSE_BY_CLOSE, /**< Close the handle(s). */
CLOSE_BY_DESTROY, CLOSE_BY_DESTROY, /**< Destroy the handle(s). */
CLOSE_BY_SHUTDOWN, CLOSE_BY_SHUTDOWN, /**< Deinit and reinit without closing handles. */
CLOSE_BY_CLOSE_WITH_SHUTDOWN, /**< Close handle(s) then deinit/reinit. */
CLOSE_BY_DESTROY_WITH_SHUTDOWN, /**< Destroy handle(s) then deinit/reinit. */
} close_method_t; } close_method_t;
typedef enum typedef enum
@ -62,6 +64,58 @@ static void psa_purge_key_storage( void )
#define TEST_USES_KEY_ID( key_id ) ( (void) ( key_id ) ) #define TEST_USES_KEY_ID( key_id ) ( (void) ( key_id ) )
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
/** Apply \p close_method to invalidate the specified handles:
* close it, destroy it, or do nothing;
*/
static int invalidate_handle( close_method_t close_method,
psa_key_handle_t handle )
{
switch( close_method )
{
case CLOSE_BY_CLOSE:
case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
PSA_ASSERT( psa_close_key( handle ) );
break;
case CLOSE_BY_DESTROY:
case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
PSA_ASSERT( psa_destroy_key( handle ) );
break;
case CLOSE_BY_SHUTDOWN:
break;
}
return( 1 );
exit:
return( 0 );
}
/** Restart the PSA subsystem if \p close_method says so. */
static int invalidate_psa( close_method_t close_method )
{
switch( close_method )
{
case CLOSE_BY_CLOSE:
case CLOSE_BY_DESTROY:
return( 1 );
case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
/* All keys must have been closed. */
PSA_DONE( );
break;
case CLOSE_BY_SHUTDOWN:
/* Some keys may remain behind, and we're testing that this
* properly closes them. */
mbedtls_psa_crypto_free( );
break;
}
PSA_ASSERT( psa_crypto_init( ) );
ASSERT_PSA_PRISTINE( );
return( 1 );
exit:
return( 0 );
}
/* END_HEADER */ /* END_HEADER */
/* BEGIN_DEPENDENCIES /* BEGIN_DEPENDENCIES
@ -94,19 +148,10 @@ void transient_slot_lifecycle( int usage_arg, int alg_arg,
TEST_EQUAL( psa_get_key_type( &attributes ), type ); TEST_EQUAL( psa_get_key_type( &attributes ), type );
/* Do something that invalidates the handle. */ /* Do something that invalidates the handle. */
switch( close_method ) if( ! invalidate_handle( close_method, handle ) )
{ goto exit;
case CLOSE_BY_CLOSE: if( ! invalidate_psa( close_method ) )
PSA_ASSERT( psa_close_key( handle ) ); goto exit;
break;
case CLOSE_BY_DESTROY:
PSA_ASSERT( psa_destroy_key( handle ) );
break;
case CLOSE_BY_SHUTDOWN:
PSA_DONE( );
PSA_ASSERT( psa_crypto_init( ) );
break;
}
/* Test that the handle is now invalid. */ /* Test that the handle is now invalid. */
TEST_EQUAL( psa_get_key_attributes( handle, &attributes ), TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
@ -171,19 +216,11 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
TEST_EQUAL( psa_get_key_type( &attributes ), type ); TEST_EQUAL( psa_get_key_type( &attributes ), type );
/* Do something that invalidates the handle. */ /* Do something that invalidates the handle. */
switch( close_method ) if( ! invalidate_handle( close_method, handle ) )
{ goto exit;
case CLOSE_BY_CLOSE: if( ! invalidate_psa( close_method ) )
PSA_ASSERT( psa_close_key( handle ) ); goto exit;
break;
case CLOSE_BY_DESTROY:
PSA_ASSERT( psa_destroy_key( handle ) );
break;
case CLOSE_BY_SHUTDOWN:
PSA_DONE( );
PSA_ASSERT( psa_crypto_init( ) );
break;
}
/* Test that the handle is now invalid. */ /* Test that the handle is now invalid. */
TEST_EQUAL( psa_get_key_attributes( handle, &read_attributes ), TEST_EQUAL( psa_get_key_attributes( handle, &read_attributes ),
PSA_ERROR_INVALID_HANDLE ); PSA_ERROR_INVALID_HANDLE );
@ -196,6 +233,7 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
switch( close_method ) switch( close_method )
{ {
case CLOSE_BY_CLOSE: case CLOSE_BY_CLOSE:
case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
case CLOSE_BY_SHUTDOWN: case CLOSE_BY_SHUTDOWN:
PSA_ASSERT( psa_open_key( id, &handle ) ); PSA_ASSERT( psa_open_key( id, &handle ) );
PSA_ASSERT( psa_get_key_attributes( handle, &read_attributes ) ); PSA_ASSERT( psa_get_key_attributes( handle, &read_attributes ) );
@ -230,7 +268,9 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
} }
PSA_ASSERT( psa_close_key( handle ) ); PSA_ASSERT( psa_close_key( handle ) );
break; break;
case CLOSE_BY_DESTROY: case CLOSE_BY_DESTROY:
case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
TEST_EQUAL( psa_open_key( id, &handle ), TEST_EQUAL( psa_open_key( id, &handle ),
PSA_ERROR_DOES_NOT_EXIST ); PSA_ERROR_DOES_NOT_EXIST );
break; break;