From c8000c005aa16da442e716ed89009631e3770c8a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 2 Aug 2019 20:15:51 +0200 Subject: [PATCH] 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. --- include/psa/crypto_extra.h | 61 ++++++++++++++++++++++++++++++++++ include/psa/crypto_se_driver.h | 7 ++++ include/psa/crypto_struct.h | 12 ++++++- include/psa/crypto_types.h | 11 ++++++ library/psa_crypto.c | 28 +++++++++++++++- 5 files changed, 117 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 6dfaa1300..5359b580a 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -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 */ + /**@}*/ /** diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h index f95eaeb33..69cdababa 100644 --- a/include/psa/crypto_se_driver.h +++ b/include/psa/crypto_se_driver.h @@ -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 */ /**@}*/ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 3bace6088..fbfe77e62 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -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; diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h index 1944be4b2..9af4957df 100644 --- a/include/psa/crypto_types.h +++ b/include/psa/crypto_types.h @@ -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 diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e043d7000..a54cd73bb 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -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 )