Define handles as key identifiers

Define psa_key_handle_t to be equal to
mbedtls_svc_key_id_t. Make the handle of a persistent
key be equal to its key identifier. For volatile keys,
make the key handle equal to the volatile key
identifier of the created volatile key.

The unit tests are modified just to make them compile
not to make them run successfully. They are fixed in
the subsequent commits.

Signed-off-by: Ronald Cron <ronald.cron@arm.com>
This commit is contained in:
Ronald Cron 2020-07-31 11:26:37 +02:00
parent 47a85614ed
commit c4d1b514ab
10 changed files with 209 additions and 103 deletions

View file

@ -49,34 +49,6 @@
#define inline __inline
#endif
/* Integral type representing a key handle. */
typedef uint16_t psa_key_handle_t;
#define PSA_KEY_HANDLE_INIT ( (psa_key_handle_t)0 )
/** Check whether a handle is null.
*
* \param handle Key handle.
*
* \return Non-zero if the key handle is null, zero otherwise.
*/
static inline int psa_key_handle_is_null( psa_key_handle_t handle )
{
return( handle == 0 );
}
/** Compare two handles.
*
* \param handle1 First handle.
* \param handle2 Second handle.
*
* \return Non-zero if the two handles are equal, zero otherwise.
*/
static inline int psa_key_handle_equal( psa_key_handle_t handle1,
psa_key_handle_t handle2 )
{
return( handle1 == handle2 );
}
#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
/* Building for the PSA Crypto service on a PSA platform, a key owner is a PSA

View file

@ -247,6 +247,12 @@ typedef struct
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
/*
* To support temporary both openless APIs and psa_open_key(), define
* psa_key_handle_t to be equal to mbedtls_svc_key_id_t.
*/
typedef mbedtls_svc_key_id_t psa_key_handle_t;
/**@}*/
/** \defgroup policy Key policies

View file

@ -1700,6 +1700,17 @@ static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1,
return( id1 == id2 );
}
/** Check whether a key identifier is null.
*
* \param key Key identifier.
*
* \return Non-zero if the key identifier is null, zero otherwise.
*/
static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key )
{
return( key == 0 );
}
#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
#define MBEDTLS_SVC_KEY_ID_INIT ( (mbedtls_svc_key_id_t){ 0, 0 } )
@ -1732,8 +1743,45 @@ static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1,
mbedtls_key_owner_id_equal( id1.owner, id2.owner ) );
}
/** Check whether a key identifier is null.
*
* \param key Key identifier.
*
* \return Non-zero if the key identifier is null, zero otherwise.
*/
static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key )
{
return( ( key.key_id == 0 ) && ( key.owner == 0 ) );
}
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
#define PSA_KEY_HANDLE_INIT MBEDTLS_SVC_KEY_ID_INIT
/** Compare two handles.
*
* \param handle1 First handle.
* \param handle2 Second handle.
*
* \return Non-zero if the two handles are equal, zero otherwise.
*/
static inline int psa_key_handle_equal( psa_key_handle_t handle1,
psa_key_handle_t handle2 )
{
return( mbedtls_svc_key_id_equal( handle1, handle2 ) );
}
/** Check wether an handle is null.
*
* \param handle Handle
*
* \return Non-zero if the handle is null, zero otherwise.
*/
static inline int psa_key_handle_is_null( psa_key_handle_t handle )
{
return( mbedtls_svc_key_id_is_null( handle ) );
}
/**@}*/
/** \defgroup policy Key policies

View file

@ -1861,7 +1861,7 @@ static psa_status_t psa_start_key_creation(
if( status != PSA_SUCCESS )
return( status );
status = psa_get_empty_key_slot( handle, &volatile_key_id, p_slot );
status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
if( status != PSA_SUCCESS )
return( status );
slot = *p_slot;
@ -1870,9 +1870,19 @@ static psa_status_t psa_start_key_creation(
* creation mechanism to verify that this information is correct.
* It's automatically correct for mechanisms that use the bit-size as
* an input (generate, device) but not for those where the bit-size
* is optional (import, copy). */
* is optional (import, copy). In case of a volatile key, assign it the
* volatile key identifier associated to the slot returned to contain its
* definition. */
slot->attr = attributes->core;
if( PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) )
{
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
slot->attr.id = volatile_key_id;
#else
slot->attr.id.key_id = volatile_key_id;
#endif
}
/* Erase external-only flags from the internal copy. To access
* external-only flags, query `attributes`. Thanks to the check
@ -1928,7 +1938,9 @@ static psa_status_t psa_start_key_creation(
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
return( status );
*handle = slot->attr.id;
return( PSA_SUCCESS );
}
/** Finalize the creation of a key once its key material has been set.

View file

@ -64,36 +64,41 @@ psa_status_t psa_validate_key_id( mbedtls_svc_key_id_t key, int vendor_ok )
( key_id <= PSA_KEY_ID_VENDOR_MAX ) )
return( PSA_SUCCESS );
return( PSA_ERROR_INVALID_ARGUMENT );
return( PSA_ERROR_INVALID_HANDLE );
}
/* Access a key slot at the given handle. The handle of a key slot is
* the index of the slot in the global slot array, plus one so that handles
* start at 1 and not 0. */
psa_status_t psa_get_key_slot( psa_key_handle_t handle,
psa_key_slot_t **p_slot )
static psa_key_slot_t* psa_get_slot_from_volatile_key_id(
mbedtls_svc_key_id_t key )
{
psa_key_slot_t *slot = NULL;
psa_key_slot_t *slot;
psa_key_id_t key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key );
if( ! global_data.key_slots_initialized )
return( PSA_ERROR_BAD_STATE );
if( ( key_id < PSA_KEY_ID_VOLATILE_MIN ) ||
( key_id > PSA_KEY_ID_VOLATILE_MAX ) )
return( NULL );
/* 0 is not a valid handle under any circumstance. This
* implementation provides slots number 1 to N where N is the
* number of available slots. */
if( psa_key_handle_is_null( handle ) ||
( handle > ARRAY_LENGTH( global_data.key_slots ) ) )
return( PSA_ERROR_INVALID_HANDLE );
slot = &global_data.key_slots[handle - 1];
slot = &global_data.key_slots[ key_id - PSA_KEY_ID_VOLATILE_MIN ];
/* If the slot isn't occupied, the handle is invalid. */
if( ! psa_is_key_slot_occupied( slot ) )
return( PSA_ERROR_INVALID_HANDLE );
*p_slot = slot;
return( PSA_SUCCESS );
return( mbedtls_svc_key_id_equal( key, slot->attr.id ) ? slot : NULL );
}
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
static psa_key_slot_t* psa_get_slot_from_key_id(
mbedtls_svc_key_id_t key )
{
psa_key_slot_t *slot = &global_data.key_slots[ PSA_KEY_SLOT_COUNT ];
while( slot > &global_data.key_slots[ 0 ] )
{
slot--;
if( mbedtls_svc_key_id_equal( key, slot->attr.id ) )
return( slot );
}
return( NULL );
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
psa_status_t psa_initialize_key_slots( void )
{
/* Nothing to do: program startup and psa_wipe_all_key_slots() both
@ -115,8 +120,7 @@ void psa_wipe_all_key_slots( void )
global_data.key_slots_initialized = 0;
}
psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
psa_key_id_t *volatile_key_id,
psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot )
{
size_t slot_idx;
@ -129,7 +133,6 @@ psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
*p_slot = &global_data.key_slots[ slot_idx - 1 ];
if( ! psa_is_key_slot_occupied( *p_slot ) )
{
*handle = (psa_key_handle_t)slot_idx;
*volatile_key_id = PSA_KEY_ID_VOLATILE_MIN +
( (psa_key_id_t)slot_idx ) - 1;
@ -177,8 +180,50 @@ exit:
psa_free_persistent_key_data( key_data, key_data_length );
return( status );
}
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot )
{
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
*p_slot = NULL;
if( ! global_data.key_slots_initialized )
return( PSA_ERROR_BAD_STATE );
status = psa_validate_key_id( key, 1 );
if( status != PSA_SUCCESS )
return( status );
*p_slot = psa_get_slot_from_volatile_key_id( key );
if( *p_slot != NULL )
return( PSA_SUCCESS );
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
psa_key_id_t volatile_key_id;
*p_slot = psa_get_slot_from_key_id( key );
if( *p_slot != NULL )
return( PSA_SUCCESS );
status = psa_get_empty_key_slot( &volatile_key_id, p_slot );
if( status != PSA_SUCCESS )
return( status );
(*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
(*p_slot)->attr.id = key;
status = psa_load_persistent_key_into_slot( *p_slot );
if( status != PSA_SUCCESS )
psa_wipe_key_slot( *p_slot );
return( status );
#else
return( PSA_ERROR_DOES_NOT_EXIST );
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
}
psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime,
psa_se_drv_table_entry_t **p_drv )
{
@ -226,29 +271,18 @@ psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle )
{
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
psa_status_t status;
psa_key_id_t volatile_key_id;
psa_key_slot_t *slot;
*handle = 0;
status = psa_validate_key_id( key, 1 );
if( status != PSA_SUCCESS )
return( status );
status = psa_get_empty_key_slot( handle, &volatile_key_id, &slot );
if( status != PSA_SUCCESS )
return( status );
slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
slot->attr.id = key;
status = psa_load_persistent_key_into_slot( slot );
status = psa_get_key_slot( key, &slot );
if( status != PSA_SUCCESS )
{
psa_wipe_key_slot( slot );
*handle = PSA_KEY_HANDLE_INIT;
return( status );
}
return( status );
*handle = key;
return( PSA_SUCCESS );
#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
(void) key;

View file

@ -22,6 +22,7 @@
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
#include "psa/crypto.h"
#include "psa_crypto_core.h"
#include "psa_crypto_se.h"
/* Number of key slots (plus one because 0 is not used).
@ -45,21 +46,38 @@
*/
#define PSA_KEY_ID_VOLATILE_MAX PSA_KEY_ID_VENDOR_MAX
/** Access a key slot at the given handle.
/** Retrieve the description of a key given its identifier.
*
* \param handle Key handle to query.
* The descriptions of volatile keys and loaded persistent keys are
* stored in key slots. This function returns a pointer to the key slot
* containing the description of a key given its identifier.
*
* In case of a persistent key, the function loads the description of the key
* into a key slot if not already done.
*
* \param key Key identifier to query.
* \param[out] p_slot On success, `*p_slot` contains a pointer to the
* key slot in memory designated by \p handle.
* key slot containing the description of the key
* identified by \p key.
*
* \retval PSA_SUCCESS
* Success: \p handle is a handle to `*p_slot`. Note that `*p_slot`
* may be empty or occupied.
* \retval PSA_ERROR_INVALID_HANDLE
* \p handle is out of range or is not in use.
* \retval PSA_ERROR_BAD_STATE
* \retval #PSA_SUCCESS
* The pointer to the key slot containing the description of the key
* identified by \p key was returned.
* \retval #PSA_ERROR_BAD_STATE
* The library has not been initialized.
* \retval #PSA_ERROR_INVALID_HANDLE
* \p key is not a valid key identifier.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \p key is a persistent key identifier. The implementation does not
* have sufficient resources to load the persistent key. This can be
* due to a lack of empty key slot, or available memory.
* \retval #PSA_ERROR_DOES_NOT_EXIST
* There is no key with key identifier \p key.
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_DATA_CORRUPT
*/
psa_status_t psa_get_key_slot( psa_key_handle_t handle,
psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key,
psa_key_slot_t **p_slot );
/** Initialize the key slot structures.
@ -79,8 +97,6 @@ void psa_wipe_all_key_slots( void );
* This function returns a key slot that is available for use and is in its
* ground state (all-bits-zero).
*
* \param[out] handle On success, a slot number that can be used
* as a handle to the slot.
* \param[out] volatile_key_id On success, volatile key identifier
* associated to the returned slot.
* \param[out] p_slot On success, a pointer to the slot.
@ -89,8 +105,7 @@ void psa_wipe_all_key_slots( void );
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_BAD_STATE
*/
psa_status_t psa_get_empty_key_slot( psa_key_handle_t *handle,
psa_key_id_t *volatile_key_id,
psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id,
psa_key_slot_t **p_slot );
/** Test whether a lifetime designates a key in an external cryptoprocessor.

View file

@ -3577,8 +3577,10 @@ exit:
if( ( status != PSA_SUCCESS ) &&
( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
{
mbedtls_printf( "Failed to destroy key slot %u - error was %d",
(unsigned) slot, (int) status );
mbedtls_printf( "Failed to destroy key slot %u-%u - error was %d",
MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( slot ),
MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot ),
(int) status );
if( ret == 0 )
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
}

View file

@ -4518,8 +4518,10 @@ exit:
if( ( status != PSA_SUCCESS ) &&
( opt.query_config_mode == DFL_QUERY_CONFIG_MODE ) )
{
mbedtls_printf( "Failed to destroy key slot %u - error was %d",
(unsigned) psk_slot, (int) status );
mbedtls_printf( "Failed to destroy key slot %u-%u - error was %d",
MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( psk_slot ),
MBEDTLS_SVC_KEY_ID_GET_KEY_ID( psk_slot ),
(int) status );
}
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&

View file

@ -185,7 +185,7 @@ void validate_module_init_key_based( int count )
psa_status_t status;
uint8_t data[10] = { 0 };
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_handle_t handle = 0xdead;
psa_key_handle_t handle = mbedtls_svc_key_id_make( 0xdead, 0xdead );
int i;
for( i = 0; i < count; i++ )

View file

@ -2,6 +2,7 @@
#include <stdint.h>
#include "test/psa_crypto_helpers.h"
#include "psa_crypto_slot_management.h"
#include "psa_crypto_storage.h"
typedef enum
@ -389,7 +390,7 @@ void open_fail( int id_arg,
{
mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make( 1, id_arg );
psa_status_t expected_status = expected_status_arg;
psa_key_handle_t handle = 0xdead;
psa_key_handle_t handle = mbedtls_svc_key_id_make( 0xdead, 0xdead );
PSA_ASSERT( psa_crypto_init( ) );
@ -409,7 +410,7 @@ void create_fail( int lifetime_arg, int id_arg,
mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make( 1, id_arg );
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t expected_status = expected_status_arg;
psa_key_handle_t handle = 0xdead;
psa_key_handle_t handle = mbedtls_svc_key_id_make( 0xdead, 0xdead );
uint8_t material[1] = {'k'};
TEST_USES_KEY_ID( id );
@ -583,7 +584,7 @@ void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
psa_algorithm_t target_alg = target_alg_arg;
psa_key_handle_t target_handle = PSA_KEY_HANDLE_INIT;
psa_key_type_t target_type = target_type_arg;
psa_key_handle_t new_handle = 0xdead;
psa_key_handle_t new_handle = mbedtls_svc_key_id_make( 0xdead, 0xdead );
uint8_t *export_buffer = NULL;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_attributes_t attributes1 = PSA_KEY_ATTRIBUTES_INIT;
@ -677,6 +678,7 @@ void invalid_handle( int handle_construction,
{
psa_key_handle_t valid_handle = PSA_KEY_HANDLE_INIT;
psa_key_handle_t invalid_handle = PSA_KEY_HANDLE_INIT;
psa_key_id_t key_id;
psa_status_t close_status = close_status_arg;
psa_status_t usage_status = usage_status_arg;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
@ -700,14 +702,26 @@ void invalid_handle( int handle_construction,
invalid_handle = PSA_KEY_HANDLE_INIT;
break;
case INVALID_HANDLE_UNOPENED:
/* We can't easily construct a handle that's never been opened
* without knowing how the implementation constructs handle
* values. The current test code assumes that valid handles
* are in a range between 1 and some maximum. */
if( valid_handle == 1 )
invalid_handle = 2;
/*
* MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile
* key identifier as the imported key is a volatile key. Volatile
* key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN
* to PSA_KEY_ID_VOLATILE_MAX included. Thus pick a key identifier
* in the range from PSA_KEY_ID_VOLATILE_MIN to
* PSA_KEY_ID_VOLATILE_MAX different from
* MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) to build an
* unopened and thus invalid identifier.
*/
if( MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) ==
PSA_KEY_ID_VOLATILE_MIN )
key_id = PSA_KEY_ID_VOLATILE_MIN + 1;
else
invalid_handle = valid_handle - 1;
key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) - 1;
invalid_handle =
mbedtls_svc_key_id_make( 0, key_id );
break;
case INVALID_HANDLE_CLOSED:
PSA_ASSERT( psa_import_key( &attributes,
@ -716,7 +730,8 @@ void invalid_handle( int handle_construction,
PSA_ASSERT( psa_destroy_key( invalid_handle ) );
break;
case INVALID_HANDLE_HUGE:
invalid_handle = (psa_key_handle_t) ( -1 );
invalid_handle =
mbedtls_svc_key_id_make( 0, PSA_KEY_ID_VENDOR_MAX + 1 );
break;
default:
TEST_ASSERT( ! "unknown handle construction" );