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