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
2 changed files with 89 additions and 10 deletions
|
@ -950,7 +950,20 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle )
|
|||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
driver = psa_get_se_driver_entry( slot->lifetime );
|
||||
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 );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_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) */
|
||||
|
||||
#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 );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
@ -1382,8 +1407,10 @@ static psa_status_t psa_start_key_creation(
|
|||
slot->type = attributes->type;
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/* Find a slot number. Don't yet mark it as allocated in case
|
||||
* the key creation fails or there is a power failure. */
|
||||
/* Find a slot number for the new key. Save the slot number in
|
||||
* 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 )
|
||||
{
|
||||
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 )
|
||||
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 */
|
||||
|
||||
return( status );
|
||||
|
@ -1459,6 +1493,9 @@ static psa_status_t psa_finish_key_creation(
|
|||
psa_destroy_persistent_key( slot->persistent_storage_id );
|
||||
return( status );
|
||||
}
|
||||
status = psa_crypto_stop_transaction( );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
}
|
||||
#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
|
||||
* to internal storage), we need to destroy the key in the secure
|
||||
* 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 */
|
||||
|
||||
psa_wipe_key_slot( slot );
|
||||
|
@ -5674,6 +5716,19 @@ psa_status_t psa_crypto_init( void )
|
|||
if( status != PSA_SUCCESS )
|
||||
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. */
|
||||
global_data.initialized = 1;
|
||||
|
||||
|
|
|
@ -29,15 +29,9 @@
|
|||
extern "C" {
|
||||
#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_se_driver.h"
|
||||
|
||||
#include <stdint.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 )
|
||||
|
||||
/** 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.
|
||||
*
|
||||
* This type is designed to be serialized by writing the memory representation
|
||||
|
@ -266,7 +276,21 @@ typedef union
|
|||
struct psa_crypto_transaction_unknown_s
|
||||
{
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
uint32_t unused2;
|
||||
uint64_t unused3;
|
||||
uint64_t unused4;
|
||||
} 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;
|
||||
|
||||
/** The single active transaction.
|
||||
|
|
Loading…
Reference in a new issue