@@ -1514,6 +1514,7 @@ typedef enum
1514
1514
PSA_KEY_CREATION_GENERATE ,
1515
1515
PSA_KEY_CREATION_DERIVE ,
1516
1516
PSA_KEY_CREATION_COPY ,
1517
+ PSA_KEY_CREATION_REGISTER ,
1517
1518
} psa_key_creation_method_t ;
1518
1519
1519
1520
/** Prepare a key slot to receive key material.
@@ -1580,7 +1581,8 @@ static psa_status_t psa_start_key_creation(
1580
1581
slot -> attr .flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ;
1581
1582
1582
1583
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1583
- /* For a key in a secure element, we need to do three things:
1584
+ /* For a key in a secure element, we need to do three things
1585
+ * when creating a key (but not when registering an existing key):
1584
1586
* create the key file in internal storage, create the
1585
1587
* key inside the secure element, and update the driver's
1586
1588
* persistent data. Start a transaction that will encompass these
@@ -1593,7 +1595,7 @@ static psa_status_t psa_start_key_creation(
1593
1595
* secure element driver updates its persistent state, but we do not yet
1594
1596
* save the driver's persistent state, so that if the power fails,
1595
1597
* we can roll back to a state where the key doesn't exist. */
1596
- if ( * p_drv != NULL )
1598
+ if ( * p_drv != NULL && method != PSA_KEY_CREATION_REGISTER )
1597
1599
{
1598
1600
status = psa_find_se_slot_for_key ( attributes , * p_drv ,
1599
1601
& slot -> data .se .slot_number );
@@ -1687,7 +1689,13 @@ static psa_status_t psa_finish_key_creation(
1687
1689
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1688
1690
1689
1691
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1690
- if ( driver != NULL )
1692
+ /* Finish the transaction for a key creation. This does not
1693
+ * happen when registering an existing key. Detect this case
1694
+ * by checking whether a transaction is in progress (actual
1695
+ * creation of a key in a secure element requires a transaction,
1696
+ * but registration doesn't use one). */
1697
+ if ( driver != NULL &&
1698
+ psa_crypto_transaction .unknown .type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
1691
1699
{
1692
1700
status = psa_save_se_persistent_data ( driver );
1693
1701
if ( status != PSA_SUCCESS )
@@ -1730,9 +1738,12 @@ static void psa_fail_key_creation( psa_key_slot_t *slot,
1730
1738
* to internal storage), we need to destroy the key in the secure
1731
1739
* element. */
1732
1740
1733
- /* Abort the ongoing transaction if any. We already did what it
1734
- * takes to undo any partial creation. All that's left is to update
1735
- * the transaction data itself. */
1741
+ /* Abort the ongoing transaction if any (there may not be one if
1742
+ * the creation process failed before starting one, or if the
1743
+ * key creation is a registration of a key in a secure element).
1744
+ * Earlier functions must already have done what it takes to undo any
1745
+ * partial creation. All that's left is to update the transaction data
1746
+ * itself. */
1736
1747
(void ) psa_crypto_stop_transaction ( );
1737
1748
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1738
1749
@@ -1862,6 +1873,59 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1862
1873
return ( status );
1863
1874
}
1864
1875
1876
+ #if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1877
+ psa_status_t mbedtls_psa_register_se_key (
1878
+ const psa_key_attributes_t * attributes )
1879
+ {
1880
+ psa_status_t status ;
1881
+ psa_key_slot_t * slot = NULL ;
1882
+ psa_se_drv_table_entry_t * driver = NULL ;
1883
+ const psa_drv_se_t * drv ;
1884
+ psa_key_handle_t handle = 0 ;
1885
+
1886
+ /* Leaving attributes unspecified is not currently supported.
1887
+ * It could make sense to query the key type and size from the
1888
+ * secure element, but not all secure elements support this
1889
+ * and the driver HAL doesn't currently support it. */
1890
+ if ( psa_get_key_type ( attributes ) == PSA_KEY_TYPE_NONE )
1891
+ return ( PSA_ERROR_NOT_SUPPORTED );
1892
+ if ( psa_get_key_bits ( attributes ) == 0 )
1893
+ return ( PSA_ERROR_NOT_SUPPORTED );
1894
+
1895
+ status = psa_start_key_creation ( PSA_KEY_CREATION_REGISTER , attributes ,
1896
+ & handle , & slot , & driver );
1897
+ if ( status != PSA_SUCCESS )
1898
+ goto exit ;
1899
+
1900
+ if ( driver == NULL )
1901
+ {
1902
+ status = PSA_ERROR_INVALID_ARGUMENT ;
1903
+ goto exit ;
1904
+ }
1905
+ drv = psa_get_se_driver_methods ( driver );
1906
+
1907
+ if ( psa_get_key_slot_number ( attributes ,
1908
+ & slot -> data .se .slot_number ) != PSA_SUCCESS )
1909
+ {
1910
+ /* The application didn't specify a slot number. This doesn't
1911
+ * make sense when registering a slot. */
1912
+ status = PSA_ERROR_INVALID_ARGUMENT ;
1913
+ goto exit ;
1914
+ }
1915
+
1916
+ status = psa_finish_key_creation ( slot , driver );
1917
+
1918
+ exit :
1919
+ if ( status != PSA_SUCCESS )
1920
+ {
1921
+ psa_fail_key_creation ( slot , driver );
1922
+ }
1923
+ /* Registration doesn't keep the key in RAM. */
1924
+ psa_close_key ( handle );
1925
+ return ( status );
1926
+ }
1927
+ #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1928
+
1865
1929
static psa_status_t psa_copy_key_material ( const psa_key_slot_t * source ,
1866
1930
psa_key_slot_t * target )
1867
1931
{
0 commit comments