@@ -1520,6 +1520,7 @@ static psa_status_t psa_validate_key_attributes(
1520
1520
* In case of failure at any step, stop the sequence and call
1521
1521
* psa_fail_key_creation().
1522
1522
*
1523
+ * \param method An identification of the calling function.
1523
1524
* \param[in] attributes Key attributes for the new key.
1524
1525
* \param[out] handle On success, a handle for the allocated slot.
1525
1526
* \param[out] p_slot On success, a pointer to the prepared slot.
@@ -1532,6 +1533,7 @@ static psa_status_t psa_validate_key_attributes(
1532
1533
* You must call psa_fail_key_creation() to wipe and free the slot.
1533
1534
*/
1534
1535
static psa_status_t psa_start_key_creation (
1536
+ psa_key_creation_method_t method ,
1535
1537
const psa_key_attributes_t * attributes ,
1536
1538
psa_key_handle_t * handle ,
1537
1539
psa_key_slot_t * * p_slot ,
@@ -1540,6 +1542,7 @@ static psa_status_t psa_start_key_creation(
1540
1542
psa_status_t status ;
1541
1543
psa_key_slot_t * slot ;
1542
1544
1545
+ (void ) method ;
1543
1546
* p_drv = NULL ;
1544
1547
1545
1548
status = psa_validate_key_attributes ( attributes , p_drv );
@@ -1567,7 +1570,8 @@ static psa_status_t psa_start_key_creation(
1567
1570
slot -> attr .flags &= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ;
1568
1571
1569
1572
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1570
- /* For a key in a secure element, we need to do three things:
1573
+ /* For a key in a secure element, we need to do three things
1574
+ * when creating a key (but not when registering an existing key):
1571
1575
* create the key file in internal storage, create the
1572
1576
* key inside the secure element, and update the driver's
1573
1577
* persistent data. Start a transaction that will encompass these
@@ -1580,9 +1584,9 @@ static psa_status_t psa_start_key_creation(
1580
1584
* secure element driver updates its persistent state, but we do not yet
1581
1585
* save the driver's persistent state, so that if the power fails,
1582
1586
* we can roll back to a state where the key doesn't exist. */
1583
- if ( * p_drv != NULL )
1587
+ if ( * p_drv != NULL && method != PSA_KEY_CREATION_REGISTER )
1584
1588
{
1585
- status = psa_find_se_slot_for_key ( attributes , * p_drv ,
1589
+ status = psa_find_se_slot_for_key ( attributes , method , * p_drv ,
1586
1590
& slot -> data .se .slot_number );
1587
1591
if ( status != PSA_SUCCESS )
1588
1592
return ( status );
@@ -1674,7 +1678,13 @@ static psa_status_t psa_finish_key_creation(
1674
1678
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
1675
1679
1676
1680
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1677
- if ( driver != NULL )
1681
+ /* Finish the transaction for a key creation. This does not
1682
+ * happen when registering an existing key. Detect this case
1683
+ * by checking whether a transaction is in progress (actual
1684
+ * creation of a key in a secure element requires a transaction,
1685
+ * but registration doesn't use one). */
1686
+ if ( driver != NULL &&
1687
+ psa_crypto_transaction .unknown .type == PSA_CRYPTO_TRANSACTION_CREATE_KEY )
1678
1688
{
1679
1689
status = psa_save_se_persistent_data ( driver );
1680
1690
if ( status != PSA_SUCCESS )
@@ -1717,9 +1727,12 @@ static void psa_fail_key_creation( psa_key_slot_t *slot,
1717
1727
* to internal storage), we need to destroy the key in the secure
1718
1728
* element. */
1719
1729
1720
- /* Abort the ongoing transaction if any. We already did what it
1721
- * takes to undo any partial creation. All that's left is to update
1722
- * the transaction data itself. */
1730
+ /* Abort the ongoing transaction if any (there may not be one if
1731
+ * the creation process failed before starting one, or if the
1732
+ * key creation is a registration of a key in a secure element).
1733
+ * Earlier functions must already have done what it takes to undo any
1734
+ * partial creation. All that's left is to update the transaction data
1735
+ * itself. */
1723
1736
(void ) psa_crypto_stop_transaction ( );
1724
1737
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1725
1738
@@ -1796,7 +1809,8 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1796
1809
psa_key_slot_t * slot = NULL ;
1797
1810
psa_se_drv_table_entry_t * driver = NULL ;
1798
1811
1799
- status = psa_start_key_creation ( attributes , handle , & slot , & driver );
1812
+ status = psa_start_key_creation ( PSA_KEY_CREATION_IMPORT , attributes ,
1813
+ handle , & slot , & driver );
1800
1814
if ( status != PSA_SUCCESS )
1801
1815
goto exit ;
1802
1816
@@ -1848,6 +1862,74 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
1848
1862
return ( status );
1849
1863
}
1850
1864
1865
+ #if defined(MBEDTLS_PSA_CRYPTO_SE_C )
1866
+ psa_status_t mbedtls_psa_register_se_key (
1867
+ const psa_key_attributes_t * attributes )
1868
+ {
1869
+ psa_status_t status ;
1870
+ psa_key_slot_t * slot = NULL ;
1871
+ psa_se_drv_table_entry_t * driver = NULL ;
1872
+ const psa_drv_se_t * drv ;
1873
+ psa_key_handle_t handle = 0 ;
1874
+
1875
+ /* Leaving attributes unspecified is not currently supported.
1876
+ * It could make sense to query the key type and size from the
1877
+ * secure element, but not all secure elements support this
1878
+ * and the driver HAL doesn't currently support it. */
1879
+ if ( psa_get_key_type ( attributes ) == PSA_KEY_TYPE_NONE )
1880
+ return ( PSA_ERROR_NOT_SUPPORTED );
1881
+ if ( psa_get_key_bits ( attributes ) == 0 )
1882
+ return ( PSA_ERROR_NOT_SUPPORTED );
1883
+
1884
+ status = psa_start_key_creation ( PSA_KEY_CREATION_REGISTER , attributes ,
1885
+ & handle , & slot , & driver );
1886
+ if ( status != PSA_SUCCESS )
1887
+ goto exit ;
1888
+
1889
+ if ( driver == NULL )
1890
+ {
1891
+ status = PSA_ERROR_INVALID_ARGUMENT ;
1892
+ goto exit ;
1893
+ }
1894
+ drv = psa_get_se_driver_methods ( driver );
1895
+
1896
+ if ( psa_get_key_slot_number ( attributes ,
1897
+ & slot -> data .se .slot_number ) != PSA_SUCCESS )
1898
+ {
1899
+ /* The application didn't specify a slot number. This doesn't
1900
+ * make sense when registering a slot. */
1901
+ status = PSA_ERROR_INVALID_ARGUMENT ;
1902
+ goto exit ;
1903
+ }
1904
+
1905
+ /* If the driver has a slot number validation method, call it.
1906
+ * If it doesn't, it means the secure element is unable to validate
1907
+ * anything and so we have to trust the application. */
1908
+ if ( drv -> key_management != NULL &&
1909
+ drv -> key_management -> p_validate_slot_number != NULL )
1910
+ {
1911
+ status = drv -> key_management -> p_validate_slot_number (
1912
+ psa_get_se_driver_context ( driver ),
1913
+ attributes ,
1914
+ PSA_KEY_CREATION_REGISTER ,
1915
+ slot -> data .se .slot_number );
1916
+ if ( status != PSA_SUCCESS )
1917
+ goto exit ;
1918
+ }
1919
+
1920
+ status = psa_finish_key_creation ( slot , driver );
1921
+
1922
+ exit :
1923
+ if ( status != PSA_SUCCESS )
1924
+ {
1925
+ psa_fail_key_creation ( slot , driver );
1926
+ }
1927
+ /* Registration doesn't keep the key in RAM. */
1928
+ psa_close_key ( handle );
1929
+ return ( status );
1930
+ }
1931
+ #endif /* MBEDTLS_PSA_CRYPTO_SE_C */
1932
+
1851
1933
static psa_status_t psa_copy_key_material ( const psa_key_slot_t * source ,
1852
1934
psa_key_slot_t * target )
1853
1935
{
@@ -1899,7 +1981,8 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle,
1899
1981
if ( status != PSA_SUCCESS )
1900
1982
goto exit ;
1901
1983
1902
- status = psa_start_key_creation ( & actual_attributes ,
1984
+ status = psa_start_key_creation ( PSA_KEY_CREATION_COPY ,
1985
+ & actual_attributes ,
1903
1986
target_handle , & target_slot , & driver );
1904
1987
if ( status != PSA_SUCCESS )
1905
1988
goto exit ;
@@ -4817,7 +4900,8 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut
4817
4900
psa_status_t status ;
4818
4901
psa_key_slot_t * slot = NULL ;
4819
4902
psa_se_drv_table_entry_t * driver = NULL ;
4820
- status = psa_start_key_creation ( attributes , handle , & slot , & driver );
4903
+ status = psa_start_key_creation ( PSA_KEY_CREATION_DERIVE ,
4904
+ attributes , handle , & slot , & driver );
4821
4905
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
4822
4906
if ( driver != NULL )
4823
4907
{
@@ -5863,7 +5947,8 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
5863
5947
psa_status_t status ;
5864
5948
psa_key_slot_t * slot = NULL ;
5865
5949
psa_se_drv_table_entry_t * driver = NULL ;
5866
- status = psa_start_key_creation ( attributes , handle , & slot , & driver );
5950
+ status = psa_start_key_creation ( PSA_KEY_CREATION_GENERATE ,
5951
+ attributes , handle , & slot , & driver );
5867
5952
#if defined(MBEDTLS_PSA_CRYPTO_SE_C )
5868
5953
if ( driver != NULL )
5869
5954
{
0 commit comments