Skip to content

Commit f8ec001

Browse files
New function mbedtls_psa_register_se_key
Register an existing key in a secure element. Minimal implementation that doesn't call any driver method and just lets the application declare whatever it wants.
1 parent d63b7a6 commit f8ec001

File tree

4 files changed

+176
-6
lines changed

4 files changed

+176
-6
lines changed

include/psa/crypto_extra.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,44 @@ static inline void psa_clear_key_slot_number(
175175
attributes->core.flags &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
176176
}
177177

178+
/** Register a key that is already present in a secure element.
179+
*
180+
* The key must be located in a secure element designated by the
181+
* lifetime field in \p attributes, in the slot set with
182+
* psa_set_key_slot_number() in the attribute structure.
183+
* This function makes the key available through the key identifier
184+
* specified in \p attributes.
185+
*
186+
* \param[in] attributes The attributes of the existing key.
187+
*
188+
* \retval #PSA_SUCCESS
189+
* The key was successfully registered.
190+
* Note that depending on the design of the driver, this may or may
191+
* not guarantee that a key actually exists in the designated slot
192+
* and is compatible with the specified attributes.
193+
* \retval #PSA_ERROR_ALREADY_EXISTS
194+
* There is already a key with the identifier specified in
195+
* \p attributes.
196+
* \retval #PSA_ERROR_INVALID_ARGUMENT
197+
* \p attributes specifies a lifetime which is not located
198+
* in a secure element.
199+
* \retval #PSA_ERROR_INVALID_ARGUMENT
200+
* No slot number is specified in \p attributes,
201+
* or the specified slot number is not valid.
202+
* \retval #PSA_ERROR_NOT_PERMITTED
203+
* The caller is not authorized to register the specified key slot.
204+
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
205+
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
206+
* \retval #PSA_ERROR_HARDWARE_FAILURE
207+
* \retval #PSA_ERROR_CORRUPTION_DETECTED
208+
* \retval #PSA_ERROR_BAD_STATE
209+
* The library has not been previously initialized by psa_crypto_init().
210+
* It is implementation-dependent whether a failure to initialize
211+
* results in this error code.
212+
*/
213+
psa_status_t mbedtls_psa_register_se_key(
214+
const psa_key_attributes_t *attributes);
215+
178216
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
179217

180218
/**@}*/

library/psa_crypto.c

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,7 @@ typedef enum
15131513
PSA_KEY_CREATION_GENERATE,
15141514
PSA_KEY_CREATION_DERIVE,
15151515
PSA_KEY_CREATION_COPY,
1516+
PSA_KEY_CREATION_REGISTER,
15161517
} psa_key_creation_method_t;
15171518

15181519
/** Prepare a key slot to receive key material.
@@ -1575,7 +1576,8 @@ static psa_status_t psa_start_key_creation(
15751576
slot->attr.flags |= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY;
15761577

15771578
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1578-
/* For a key in a secure element, we need to do three things:
1579+
/* For a key in a secure element, we need to do three things
1580+
* when creating a key (but not when registering an existing key):
15791581
* create the key file in internal storage, create the
15801582
* key inside the secure element, and update the driver's
15811583
* persistent data. Start a transaction that will encompass these
@@ -1588,7 +1590,7 @@ static psa_status_t psa_start_key_creation(
15881590
* secure element driver updates its persistent state, but we do not yet
15891591
* save the driver's persistent state, so that if the power fails,
15901592
* we can roll back to a state where the key doesn't exist. */
1591-
if( *p_drv != NULL )
1593+
if( *p_drv != NULL && method != PSA_KEY_CREATION_REGISTER )
15921594
{
15931595
status = psa_find_se_slot_for_key( attributes, *p_drv,
15941596
&slot->data.se.slot_number );
@@ -1682,7 +1684,13 @@ static psa_status_t psa_finish_key_creation(
16821684
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
16831685

16841686
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1685-
if( driver != NULL )
1687+
/* Finish the transaction for a key creation. This does not
1688+
* happen when registering an existing key. Detect this case
1689+
* by checking whether a transaction is in progress (actual
1690+
* creation of a key in a secure element requires a transaction,
1691+
* but registration doesn't use one). */
1692+
if( driver != NULL &&
1693+
psa_crypto_transaction.unknown.type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
16861694
{
16871695
status = psa_save_se_persistent_data( driver );
16881696
if( status != PSA_SUCCESS )
@@ -1725,9 +1733,12 @@ static void psa_fail_key_creation( psa_key_slot_t *slot,
17251733
* to internal storage), we need to destroy the key in the secure
17261734
* element. */
17271735

1728-
/* Abort the ongoing transaction if any. We already did what it
1729-
* takes to undo any partial creation. All that's left is to update
1730-
* the transaction data itself. */
1736+
/* Abort the ongoing transaction if any (there may not be one if
1737+
* the creation process failed before starting one, or if the
1738+
* key creation is a registration of a key in a secure element).
1739+
* Earlier functions must already have done what it takes to undo any
1740+
* partial creation. All that's left is to update the transaction data
1741+
* itself. */
17311742
(void) psa_crypto_stop_transaction( );
17321743
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
17331744

@@ -1857,6 +1868,59 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
18571868
return( status );
18581869
}
18591870

1871+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
1872+
psa_status_t mbedtls_psa_register_se_key(
1873+
const psa_key_attributes_t *attributes )
1874+
{
1875+
psa_status_t status;
1876+
psa_key_slot_t *slot = NULL;
1877+
psa_se_drv_table_entry_t *driver = NULL;
1878+
const psa_drv_se_t *drv;
1879+
psa_key_handle_t handle = 0;
1880+
1881+
/* Leaving attributes unspecified is not currently supported.
1882+
* It could make sense to query the key type and size from the
1883+
* secure element, but not all secure elements support this
1884+
* and the driver HAL doesn't currently support it. */
1885+
if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_NONE )
1886+
return( PSA_ERROR_NOT_SUPPORTED );
1887+
if( psa_get_key_bits( attributes ) == 0 )
1888+
return( PSA_ERROR_NOT_SUPPORTED );
1889+
1890+
status = psa_start_key_creation( PSA_KEY_CREATION_REGISTER, attributes,
1891+
&handle, &slot, &driver );
1892+
if( status != PSA_SUCCESS )
1893+
goto exit;
1894+
1895+
if( driver == NULL )
1896+
{
1897+
status = PSA_ERROR_INVALID_ARGUMENT;
1898+
goto exit;
1899+
}
1900+
drv = psa_get_se_driver_methods( driver );
1901+
1902+
if ( psa_get_key_slot_number( attributes,
1903+
&slot->data.se.slot_number ) != PSA_SUCCESS )
1904+
{
1905+
/* The application didn't specify a slot number. This doesn't
1906+
* make sense when registering a slot. */
1907+
status = PSA_ERROR_INVALID_ARGUMENT;
1908+
goto exit;
1909+
}
1910+
1911+
status = psa_finish_key_creation( slot, driver );
1912+
1913+
exit:
1914+
if( status != PSA_SUCCESS )
1915+
{
1916+
psa_fail_key_creation( slot, driver );
1917+
}
1918+
/* Registration doesn't keep the key in RAM. */
1919+
psa_close_key( handle );
1920+
return( status );
1921+
}
1922+
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1923+
18601924
static psa_status_t psa_copy_key_material( const psa_key_slot_t *source,
18611925
psa_key_slot_t *target )
18621926
{

tests/suites/test_suite_psa_crypto_se_driver_hal.data

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,15 @@ key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_
110110

111111
Generate key: not supported
112112
generate_key_not_supported:PSA_KEY_TYPE_AES:128
113+
114+
Key registration: smoke test
115+
register_key_smoke_test:MIN_DRIVER_LIFETIME:PSA_SUCCESS
116+
117+
Key registration: invalid lifetime (volatile)
118+
register_key_smoke_test:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT
119+
120+
Key registration: invalid lifetime (internal storage)
121+
register_key_smoke_test:PSA_KEY_LIFETIME_PERSISTENT:PSA_ERROR_INVALID_ARGUMENT
122+
123+
Key registration: invalid lifetime (no registered driver)
124+
register_key_smoke_test:MIN_DRIVER_LIFETIME + 1:PSA_ERROR_INVALID_ARGUMENT

tests/suites/test_suite_psa_crypto_se_driver_hal.function

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,3 +710,59 @@ exit:
710710
psa_purge_storage( );
711711
}
712712
/* END_CASE */
713+
714+
/* BEGIN_CASE */
715+
void register_key_smoke_test( int lifetime_arg, int expected_status_arg )
716+
{
717+
psa_key_lifetime_t lifetime = lifetime_arg;
718+
psa_status_t expected_status = expected_status_arg;
719+
psa_drv_se_t driver;
720+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
721+
psa_key_id_t id = 1;
722+
size_t bit_size = 48;
723+
psa_key_slot_number_t wanted_slot = 0x123456789;
724+
psa_key_handle_t handle = 0;
725+
psa_status_t status;
726+
727+
memset( &driver, 0, sizeof( driver ) );
728+
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
729+
730+
PSA_ASSERT( psa_register_se_driver( MIN_DRIVER_LIFETIME, &driver ) );
731+
PSA_ASSERT( psa_crypto_init( ) );
732+
733+
psa_set_key_id( &attributes, id );
734+
psa_set_key_lifetime( &attributes, lifetime );
735+
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
736+
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
737+
psa_set_key_bits( &attributes, bit_size );
738+
psa_set_key_slot_number( &attributes, wanted_slot );
739+
740+
status = mbedtls_psa_register_se_key( &attributes );
741+
TEST_EQUAL( status, expected_status );
742+
743+
if( status != PSA_SUCCESS )
744+
goto exit;
745+
746+
/* Test that the key exists and has the expected attributes. */
747+
PSA_ASSERT( psa_open_key( id, &handle ) );
748+
if( ! check_key_attributes( handle, &attributes ) )
749+
goto exit;
750+
PSA_ASSERT( psa_close_key( handle ) );
751+
752+
/* Restart and try again. */
753+
PSA_DONE( );
754+
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
755+
PSA_ASSERT( psa_crypto_init( ) );
756+
PSA_ASSERT( psa_open_key( id, &handle ) );
757+
if( ! check_key_attributes( handle, &attributes ) )
758+
goto exit;
759+
/* This time, destroy the key. */
760+
PSA_ASSERT( psa_destroy_key( handle ) );
761+
762+
exit:
763+
psa_reset_key_attributes( &attributes );
764+
psa_destroy_key( handle );
765+
PSA_DONE( );
766+
psa_purge_storage( );
767+
}
768+
/* END_CASE */

0 commit comments

Comments
 (0)