Add slot_number attribute

Add a slot_number field to psa_key_attributes_t and getter/setter
functions. Since slot numbers can have the value 0, indicate the
presence of the field via a separate flag.

In psa_get_key_attributes(), report the slot number if the key is in a
secure element.

When creating a key, for now, applications cannot choose a slot
number. A subsequent commit will add this capability in the secure
element HAL.
This commit is contained in:
Gilles Peskine 2019-08-02 20:15:51 +02:00
parent 74f3352b05
commit c8000c005a
5 changed files with 117 additions and 2 deletions

View File

@ -104,6 +104,67 @@ static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
return( attributes->core.policy.alg2 );
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/** Retrieve the slot number where a key is stored.
*
* A slot number is only defined for keys that are stored in a secure
* element.
*
* This information is only useful if the secure element is not entirely
* managed through the PSA Cryptography API. It is up to the secure
* element driver to decide how PSA slot numbers map to any other interface
* that the secure element may have.
*
* \param[in] attributes The key attribute structure to query.
* \param[out] slot_number On success, the slot number containing the key.
*
* \retval #PSA_SUCCESS
* The key is located in a secure element, and \p *slot_number
* indicates the slot number that contains it.
* \retval #PSA_ERROR_NOT_PERMITTED
* The caller is not permitted to query the slot number.
* Mbed Crypto currently does not return this error.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The key is not located in a secure element.
*/
psa_status_t psa_get_key_slot_number(
const psa_key_attributes_t *attributes,
psa_key_slot_number_t *slot_number );
/** Choose the slot number where a key is stored.
*
* This function declares a slot number in the specified attribute
* structure.
*
* A slot number is only meaningful for keys that are stored in a secure
* element. It is up to the secure element driver to decide how PSA slot
* numbers map to any other interface that the secure element may have.
*
* \note Setting a slot number in key attributes for a key creation can
* cause the following errors when creating the key:
* - #PSA_ERROR_NOT_SUPPORTED if the selected secure element does
* not support choosing a specific slot number.
* - #PSA_ERROR_NOT_PERMITTED if the caller is not permitted to
* choose slot numbers in general or to choose this specific slot.
* - #PSA_ERROR_INVALID_ARGUMENT if the chosen slot number is not
* valid in general or not valid for this specific key.
* - #PSA_ERROR_ALREADY_EXISTS if there is already a key in the
* selected slot.
*
* \param[out] attributes The attribute structure to write to.
* \param slot_number The slot number to set.
*/
static inline void psa_set_key_slot_number(
psa_key_attributes_t *attributes,
psa_key_slot_number_t slot_number )
{
attributes->core.flags |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER;
attributes->slot_number = slot_number;
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
/**@}*/
/**

View File

@ -134,10 +134,17 @@ typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context,
void *persistent_data,
psa_key_lifetime_t lifetime);
#if defined(__DOXYGEN_ONLY__) || !defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* Mbed Crypto with secure element support enabled defines this type in
* crypto_types.h because it is also visible to applications through an
* implementation-specific extension.
* For the PSA Cryptography specification, this type is only visible
* via crypto_se_driver.h. */
/** An internal designation of a key slot between the core part of the
* PSA Crypto implementation and the driver. The meaning of this value
* is driver-dependent. */
typedef uint64_t psa_key_slot_number_t;
#endif /* __DOXYGEN_ONLY__ || !MBEDTLS_PSA_CRYPTO_SE_C */
/**@}*/

View File

@ -331,11 +331,13 @@ typedef uint16_t psa_key_bits_t;
*/
typedef uint16_t psa_key_attributes_flag_t;
#define MBEDLTS_PSA_KA_FLAG_SLOT_NUMBER ( (psa_key_attributes_flag_t) 0x0001 )
#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \
( (psa_key_attributes_flag_t) 0x0001 )
/* A mask of key attribute flags used externally only.
* Only meant for internal checks inside the library. */
#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \
MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \
0 )
/* A mask of key attribute flags used both internally and externally.
@ -358,11 +360,19 @@ typedef struct
struct psa_key_attributes_s
{
psa_core_key_attributes_t core;
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_key_slot_number_t slot_number;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
void *domain_parameters;
size_t domain_parameters_size;
};
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0}
#else
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
#endif
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
{
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;

View File

@ -244,6 +244,17 @@ typedef uint32_t psa_key_usage_t;
*/
typedef struct psa_key_attributes_s psa_key_attributes_t;
#ifndef __DOXYGEN_ONLY__
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* Mbed Crypto defines this type in crypto_types.h because it is also
* visible to applications through an implementation-specific extension.
* For the PSA Cryptography specification, this type is only visible
* via crypto_se_driver.h. */
typedef uint64_t psa_key_slot_number_t;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
#endif /* !__DOXYGEN_ONLY__ */
/**@}*/
/** \defgroup derivation Key derivation

View File

@ -1187,6 +1187,13 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
return( status );
attributes->core = slot->attr;
attributes->core.flags &= ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY |
MBEDTLS_PSA_KA_MASK_DUAL_USE );
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
if( psa_key_slot_is_external( slot ) )
psa_set_key_slot_number( attributes, slot->data.se.slot_number );
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
switch( slot->attr.type )
{
@ -1196,7 +1203,7 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
/* TOnogrepDO: reporting the public exponent for opaque keys
* is not yet implemented. */
if( psa_get_se_driver( slot->attr.lifetime, NULL, NULL ) )
if( psa_key_slot_is_external( slot ) )
break;
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
status = psa_get_rsa_public_exponent( slot->data.rsa, attributes );
@ -1212,6 +1219,21 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle,
return( status );
}
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
psa_status_t psa_get_key_slot_number(
const psa_key_attributes_t *attributes,
psa_key_slot_number_t *slot_number )
{
if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
{
*slot_number = attributes->slot_number;
return( PSA_SUCCESS );
}
else
return( PSA_ERROR_INVALID_ARGUMENT );
}
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C)
static int pk_write_pubkey_simple( mbedtls_pk_context *key,
unsigned char *buf, size_t size )
@ -1557,6 +1579,10 @@ static psa_status_t psa_start_key_creation(
* we can roll back to a state where the key doesn't exist. */
if( *p_drv != NULL )
{
/* Choosing a slot number is not supported yet. */
if( attributes->core.flags & MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER )
return( PSA_ERROR_NOT_SUPPORTED );
status = psa_find_se_slot_for_key( attributes, *p_drv,
&slot->data.se.slot_number );
if( status != PSA_SUCCESS )