@@ -1513,6 +1513,7 @@ typedef enum
1513
1513
PSA_KEY_CREATION_GENERATE ,
1514
1514
PSA_KEY_CREATION_DERIVE ,
1515
1515
PSA_KEY_CREATION_COPY ,
1516
+ PSA_KEY_CREATION_REGISTER ,
1516
1517
} psa_key_creation_method_t ;
1517
1518
1518
1519
/** Prepare a key slot to receive key material.
@@ -1575,7 +1576,8 @@ static psa_status_t psa_start_key_creation(
1575
1576
slot -> attr .flags |= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ;
1576
1577
1577
1578
#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):
1579
1581
* create the key file in internal storage, create the
1580
1582
* key inside the secure element, and update the driver's
1581
1583
* persistent data. Start a transaction that will encompass these
@@ -1588,7 +1590,7 @@ static psa_status_t psa_start_key_creation(
1588
1590
* secure element driver updates its persistent state, but we do not yet
1589
1591
* save the driver's persistent state, so that if the power fails,
1590
1592
* 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 )
1592
1594
{
1593
1595
status = psa_find_se_slot_for_key ( attributes , * p_drv ,
1594
1596
& slot -> data .se .slot_number );
@@ -1682,7 +1684,13 @@ static psa_status_t psa_finish_key_creation(
1682
1684
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1683
1685
1684
1686
#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 )
1686
1694
{
1687
1695
status = psa_save_se_persistent_data ( driver );
1688
1696
if ( status != PSA_SUCCESS )
@@ -1725,9 +1733,12 @@ static void psa_fail_key_creation( psa_key_slot_t *slot,
1725
1733
* to internal storage), we need to destroy the key in the secure
1726
1734
* element. */
1727
1735
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. */
1731
1742
(void ) psa_crypto_stop_transaction ( );
1732
1743
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1733
1744
@@ -1857,6 +1868,59 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1857
1868
return ( status );
1858
1869
}
1859
1870
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
+
1860
1924
static psa_status_t psa_copy_key_material ( const psa_key_slot_t * source ,
1861
1925
psa_key_slot_t * target )
1862
1926
{
0 commit comments