mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-04-25 00:02:42 +00:00
Do secure element key creation and destruction in a transaction
Key creation and key destruction for a key in a secure element both require updating three pieces of data: the key data in the secure element, the key metadata in internal storage, and the SE driver's persistent data. Perform these actions in a transaction so that recovery is possible if the action is interrupted midway.
This commit is contained in:
parent
c8336cb8f9
commit
fc76265385
@ -950,7 +950,20 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle )
|
|||||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||||
driver = psa_get_se_driver_entry( slot->lifetime );
|
driver = psa_get_se_driver_entry( slot->lifetime );
|
||||||
if( driver != NULL )
|
if( driver != NULL )
|
||||||
|
{
|
||||||
|
psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY );
|
||||||
|
psa_crypto_transaction.key.lifetime = slot->lifetime;
|
||||||
|
psa_crypto_transaction.key.slot = slot->data.se.slot_number;
|
||||||
|
psa_crypto_transaction.key.id = slot->persistent_storage_id;
|
||||||
|
status = psa_crypto_save_transaction( );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
{
|
||||||
|
/* TOnogrepDO: destroy what can be destroyed anyway */
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
|
||||||
status = psa_destroy_se_key( driver, slot->data.se.slot_number );
|
status = psa_destroy_se_key( driver, slot->data.se.slot_number );
|
||||||
|
}
|
||||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||||
@ -961,6 +974,18 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle )
|
|||||||
}
|
}
|
||||||
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||||
|
if( driver != NULL )
|
||||||
|
{
|
||||||
|
status = psa_crypto_stop_transaction( );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
{
|
||||||
|
/* TOnogrepDO: destroy what can be destroyed anyway */
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||||
|
|
||||||
status = psa_wipe_key_slot( slot );
|
status = psa_wipe_key_slot( slot );
|
||||||
if( status != PSA_SUCCESS )
|
if( status != PSA_SUCCESS )
|
||||||
return( status );
|
return( status );
|
||||||
@ -1382,8 +1407,10 @@ static psa_status_t psa_start_key_creation(
|
|||||||
slot->type = attributes->type;
|
slot->type = attributes->type;
|
||||||
|
|
||||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||||
/* Find a slot number. Don't yet mark it as allocated in case
|
/* Find a slot number for the new key. Save the slot number in
|
||||||
* the key creation fails or there is a power failure. */
|
* persistent storage, but do not yet save the driver's persistent
|
||||||
|
* state, so that if the power fails during the key creation process,
|
||||||
|
* we can roll back to a state where the key doesn't exist. */
|
||||||
if( *p_drv != NULL )
|
if( *p_drv != NULL )
|
||||||
{
|
{
|
||||||
status = psa_find_se_slot_for_key( attributes, *p_drv,
|
status = psa_find_se_slot_for_key( attributes, *p_drv,
|
||||||
@ -1391,6 +1418,13 @@ static psa_status_t psa_start_key_creation(
|
|||||||
if( status != PSA_SUCCESS )
|
if( status != PSA_SUCCESS )
|
||||||
return( status );
|
return( status );
|
||||||
}
|
}
|
||||||
|
psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY );
|
||||||
|
psa_crypto_transaction.key.lifetime = slot->lifetime;
|
||||||
|
psa_crypto_transaction.key.slot = slot->data.se.slot_number;
|
||||||
|
psa_crypto_transaction.key.id = slot->persistent_storage_id;
|
||||||
|
status = psa_crypto_save_transaction( );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||||
|
|
||||||
return( status );
|
return( status );
|
||||||
@ -1459,6 +1493,9 @@ static psa_status_t psa_finish_key_creation(
|
|||||||
psa_destroy_persistent_key( slot->persistent_storage_id );
|
psa_destroy_persistent_key( slot->persistent_storage_id );
|
||||||
return( status );
|
return( status );
|
||||||
}
|
}
|
||||||
|
status = psa_crypto_stop_transaction( );
|
||||||
|
if( status != PSA_SUCCESS )
|
||||||
|
return( status );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||||
|
|
||||||
@ -1490,6 +1527,11 @@ static void psa_fail_key_creation( psa_key_slot_t *slot,
|
|||||||
* element, and the failure happened later (when saving metadata
|
* element, and the failure happened later (when saving metadata
|
||||||
* to internal storage), we need to destroy the key in the secure
|
* to internal storage), we need to destroy the key in the secure
|
||||||
* element. */
|
* element. */
|
||||||
|
|
||||||
|
/* Abort the ongoing transaction if any. We already did what it
|
||||||
|
* takes to undo any partial creation. All that's left is to update
|
||||||
|
* the transaction data itself. */
|
||||||
|
(void) psa_crypto_stop_transaction( );
|
||||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||||
|
|
||||||
psa_wipe_key_slot( slot );
|
psa_wipe_key_slot( slot );
|
||||||
@ -5674,6 +5716,19 @@ psa_status_t psa_crypto_init( void )
|
|||||||
if( status != PSA_SUCCESS )
|
if( status != PSA_SUCCESS )
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||||
|
status = psa_crypto_load_transaction( );
|
||||||
|
if( status == PSA_SUCCESS )
|
||||||
|
{
|
||||||
|
/*TOnogrepDO: complete or abort the transaction*/
|
||||||
|
}
|
||||||
|
else if( status == PSA_ERROR_DOES_NOT_EXIST )
|
||||||
|
{
|
||||||
|
/* There's no transaction to complete. It's all good. */
|
||||||
|
status = PSA_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||||
|
|
||||||
/* All done. */
|
/* All done. */
|
||||||
global_data.initialized = 1;
|
global_data.initialized = 1;
|
||||||
|
|
||||||
|
@ -29,15 +29,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
|
|
||||||
* in each of its header files. */
|
|
||||||
#if defined(MBEDTLS_CONFIG_FILE)
|
|
||||||
#include MBEDTLS_CONFIG_FILE
|
|
||||||
#else
|
|
||||||
#include "mbedtls/config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "psa/crypto.h"
|
#include "psa/crypto.h"
|
||||||
|
#include "psa/crypto_se_driver.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -223,6 +217,22 @@ typedef uint16_t psa_crypto_transaction_type_t;
|
|||||||
*/
|
*/
|
||||||
#define PSA_CRYPTO_TRANSACTION_NONE ( (psa_crypto_transaction_type_t) 0x0000 )
|
#define PSA_CRYPTO_TRANSACTION_NONE ( (psa_crypto_transaction_type_t) 0x0000 )
|
||||||
|
|
||||||
|
/** A key creation transaction.
|
||||||
|
*
|
||||||
|
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||||
|
* Keys in RAM or in internal storage are created atomically in storage
|
||||||
|
* (simple file creation), so they do not need a transaction mechanism.
|
||||||
|
*/
|
||||||
|
#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ( (psa_crypto_transaction_type_t) 0x0001 )
|
||||||
|
|
||||||
|
/** A key destruction transaction.
|
||||||
|
*
|
||||||
|
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||||
|
* Keys in RAM or in internal storage are destroyed atomically in storage
|
||||||
|
* (simple file deletion), so they do not need a transaction mechanism.
|
||||||
|
*/
|
||||||
|
#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ( (psa_crypto_transaction_type_t) 0x0002 )
|
||||||
|
|
||||||
/** Transaction data.
|
/** Transaction data.
|
||||||
*
|
*
|
||||||
* This type is designed to be serialized by writing the memory representation
|
* This type is designed to be serialized by writing the memory representation
|
||||||
@ -266,7 +276,21 @@ typedef union
|
|||||||
struct psa_crypto_transaction_unknown_s
|
struct psa_crypto_transaction_unknown_s
|
||||||
{
|
{
|
||||||
psa_crypto_transaction_type_t type;
|
psa_crypto_transaction_type_t type;
|
||||||
|
uint16_t unused1;
|
||||||
|
uint32_t unused2;
|
||||||
|
uint64_t unused3;
|
||||||
|
uint64_t unused4;
|
||||||
} unknown;
|
} unknown;
|
||||||
|
/* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or
|
||||||
|
* #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */
|
||||||
|
struct psa_crypto_transaction_key_s
|
||||||
|
{
|
||||||
|
psa_crypto_transaction_type_t type;
|
||||||
|
uint16_t unused1;
|
||||||
|
psa_key_lifetime_t lifetime;
|
||||||
|
psa_key_slot_number_t slot;
|
||||||
|
psa_key_id_t id;
|
||||||
|
} key;
|
||||||
} psa_crypto_transaction_t;
|
} psa_crypto_transaction_t;
|
||||||
|
|
||||||
/** The single active transaction.
|
/** The single active transaction.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user