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>
diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h
index 9cc27f6..4a6328a 100644
--- a/include/psa/crypto_platform.h
+++ b/include/psa/crypto_platform.h
@@ -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
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index 923b02b..b5e68d4 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -247,6 +247,12 @@
#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
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index 3eb64d8..5061ab4 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -1700,6 +1700,17 @@
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 @@
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
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 5d9b34e..f8a8c0a 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1861,7 +1861,7 @@
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 @@
* 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 @@
}
#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.
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 6303473..8ef851b 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -64,36 +64,41 @@
( 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 @@
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 @@
*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 @@
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 @@
{
#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;
diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h
index d649f53..98a1ce7 100644
--- a/library/psa_crypto_slot_management.h
+++ b/library/psa_crypto_slot_management.h
@@ -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 @@
* 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 @@
* \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.
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 16bd619..246d71a 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -3577,8 +3577,10 @@
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;
}
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index fce2e22..eb4ab0d 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -4518,8 +4518,10 @@
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 &&
diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function
index c9fdcd1..d587886 100644
--- a/tests/suites/test_suite_psa_crypto_init.function
+++ b/tests/suites/test_suite_psa_crypto_init.function
@@ -185,7 +185,7 @@
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++ )
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index a99f7de..c688474 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -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 @@
{
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 @@
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 @@
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 @@
{
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 @@
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 @@
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" );