diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 5359b580a..130ce7544 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -163,6 +163,18 @@ static inline void psa_set_key_slot_number( attributes->slot_number = slot_number; } +/** Remove the slot number attribute from a key attribute structure. + * + * This function undoes the action of psa_set_key_slot_number(). + * + * \param[out] attributes The attribute structure to write to. + */ +static inline void psa_clear_key_slot_number( + psa_key_attributes_t *attributes ) +{ + attributes->core.flags &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; +} + #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ /**@}*/ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index b04984024..4118d2f3e 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -19,6 +19,9 @@ persistence_attributes:0x1234:3:-1:0x1234:3 PSA key attributes: lifetime then id persistence_attributes:0x1234:3:0x1235:0x1235:3 +PSA key attributes: slot number +slot_number_attribute: + PSA import/export raw: 0 bytes import_export:"":PSA_KEY_TYPE_RAW_DATA:PSA_KEY_USAGE_EXPORT:0:0:0:PSA_SUCCESS:1 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 0eb6172a4..3225bef34 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1113,6 +1113,23 @@ exit: return( ok ); } +/* Assert that a key isn't reported as having a slot number. */ +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +#define ASSERT_NO_SLOT_NUMBER( attributes ) \ + do \ + { \ + psa_key_slot_number_t ASSERT_NO_SLOT_NUMBER_slot_number; \ + TEST_EQUAL( psa_get_key_slot_number( \ + attributes, \ + &ASSERT_NO_SLOT_NUMBER_slot_number ), \ + PSA_ERROR_INVALID_ARGUMENT ); \ + } \ + while( 0 ) +#else /* MBEDTLS_PSA_CRYPTO_SE_C */ +#define ASSERT_NO_SLOT_NUMBER( attributes ) \ + ( (void) 0 ) +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + /* An overapproximation of the amount of storage needed for a key of the * given type and with the given content. The API doesn't make it easy * to find a good value for the size. The current implementation doesn't @@ -1214,6 +1231,46 @@ void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg, } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_SE_C */ +void slot_number_attribute( ) +{ + psa_key_slot_number_t slot_number = 0xdeadbeef; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + /* Initially, there is no slot number. */ + TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ), + PSA_ERROR_INVALID_ARGUMENT ); + + /* Test setting a slot number. */ + psa_set_key_slot_number( &attributes, 0 ); + PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) ); + TEST_EQUAL( slot_number, 0 ); + + /* Test changing the slot number. */ + psa_set_key_slot_number( &attributes, 42 ); + PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) ); + TEST_EQUAL( slot_number, 42 ); + + /* Test clearing the slot number. */ + psa_clear_key_slot_number( &attributes ); + TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ), + PSA_ERROR_INVALID_ARGUMENT ); + + /* Clearing again should have no effect. */ + psa_clear_key_slot_number( &attributes ); + TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ), + PSA_ERROR_INVALID_ARGUMENT ); + + /* Test that reset clears the slot number. */ + psa_set_key_slot_number( &attributes, 42 ); + PSA_ASSERT( psa_get_key_slot_number( &attributes, &slot_number ) ); + TEST_EQUAL( slot_number, 42 ); + psa_reset_key_attributes( &attributes ); + TEST_EQUAL( psa_get_key_slot_number( &attributes, &slot_number ), + PSA_ERROR_INVALID_ARGUMENT ); +} +/* END_CASE */ + /* BEGIN_CASE */ void import_with_policy( int type_arg, int usage_arg, int alg_arg, @@ -1246,6 +1303,7 @@ void import_with_policy( int type_arg, TEST_EQUAL( psa_get_key_type( &got_attributes ), type ); TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage ); TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg ); + ASSERT_NO_SLOT_NUMBER( &got_attributes ); PSA_ASSERT( psa_destroy_key( handle ) ); test_operations_on_invalid_handle( handle ); @@ -1284,6 +1342,7 @@ void import_with_data( data_t *data, int type_arg, TEST_EQUAL( psa_get_key_type( &got_attributes ), type ); if( attr_bits != 0 ) TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) ); + ASSERT_NO_SLOT_NUMBER( &got_attributes ); PSA_ASSERT( psa_destroy_key( handle ) ); test_operations_on_invalid_handle( handle ); @@ -1328,6 +1387,7 @@ void import_large_key( int type_arg, int byte_size_arg, TEST_EQUAL( psa_get_key_type( &attributes ), type ); TEST_EQUAL( psa_get_key_bits( &attributes ), PSA_BYTES_TO_BITS( byte_size ) ); + ASSERT_NO_SLOT_NUMBER( &attributes ); memset( buffer, 0, byte_size + 1 ); PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) ); for( n = 0; n < byte_size; n++ ) @@ -1420,6 +1480,7 @@ void import_export( data_t *data, PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) ); TEST_EQUAL( psa_get_key_type( &got_attributes ), type ); TEST_EQUAL( psa_get_key_bits( &got_attributes ), (size_t) expected_bits ); + ASSERT_NO_SLOT_NUMBER( &got_attributes ); /* Export the key */ status = psa_export_key( handle, diff --git a/tests/suites/test_suite_psa_crypto_se_driver_hal.function b/tests/suites/test_suite_psa_crypto_se_driver_hal.function index 6ac19a60e..9a5746476 100644 --- a/tests/suites/test_suite_psa_crypto_se_driver_hal.function +++ b/tests/suites/test_suite_psa_crypto_se_driver_hal.function @@ -212,6 +212,31 @@ static int check_key_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: @@ -485,11 +510,14 @@ void key_creation_import_export( int min_slot, int restart ) /* 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 and the key 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 ) );