Merge pull request #3527 from ronald-cron-arm/key-extended-id

PSA key identifiers rework
This commit is contained in:
Gilles Peskine 2020-09-15 16:06:06 +02:00 committed by GitHub
commit dc57c25e30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 472 additions and 283 deletions

View file

@ -1258,20 +1258,17 @@
*/
//#define MBEDTLS_ENTROPY_NV_SEED
/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
*
* In PSA key storage, encode the owner of the key.
* Enable key identifiers that encode a key owner identifier.
*
* This is only meaningful when building the library as part of a
* multi-client service. When you activate this option, you must provide
* an implementation of the type psa_key_owner_id_t and a translation
* from psa_key_file_id_t to file name in all the storage backends that
* you wish to support.
* The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t
* which is currently hard-coded to be int32_t.
*
* Note that this option is meant for internal use only and may be removed
* without notice.
*/
//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
/**
* \def MBEDTLS_MEMORY_DEBUG

View file

@ -146,11 +146,11 @@ static psa_key_attributes_t psa_key_attributes_init(void);
* linkage). This function may be provided as a function-like macro,
* but in this case it must evaluate each of its arguments exactly once.
*
* \param[out] attributes The attribute structure to write to.
* \param id The persistent identifier for the key.
* \param[out] attributes The attribute structure to write to.
* \param key The persistent identifier for the key.
*/
static void psa_set_key_id(psa_key_attributes_t *attributes,
psa_key_id_t id);
static void psa_set_key_id( psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t key );
/** Set the location of a persistent key.
*
@ -192,7 +192,8 @@ static void psa_set_key_lifetime(psa_key_attributes_t *attributes,
* This value is unspecified if the attribute structure declares
* the key as volatile.
*/
static psa_key_id_t psa_get_key_id(const psa_key_attributes_t *attributes);
static mbedtls_svc_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes);
/** Retrieve the lifetime from key attributes.
*
@ -392,8 +393,9 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes);
* with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key
* always has a nonzero key identifier, set with psa_set_key_id() when
* creating the key. Implementations may provide additional pre-provisioned
* keys that can be opened with psa_open_key(). Such keys have a key identifier
* in the vendor range, as documented in the description of #psa_key_id_t.
* keys that can be opened with psa_open_key(). Such keys have an application
* key identifier in the vendor range, as documented in the description of
* #psa_key_id_t.
*
* The application must eventually close the handle with psa_close_key() or
* psa_destroy_key() to release associated resources. If the application dies
@ -408,7 +410,7 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes);
* portable to implementations that only permit a single key handle to be
* opened. See also :ref:\`key-handles\`.
*
* \param id The persistent identifier of the key.
* \param key The persistent identifier of the key.
* \param[out] handle On success, a handle to the key.
*
* \retval #PSA_SUCCESS
@ -436,9 +438,8 @@ void psa_reset_key_attributes(psa_key_attributes_t *attributes);
* It is implementation-dependent whether a failure to initialize
* results in this error code.
*/
psa_status_t psa_open_key(psa_key_id_t id,
psa_key_handle_t *handle);
psa_status_t psa_open_key( mbedtls_svc_key_id_t key,
psa_key_handle_t *handle );
/** Close a key handle.
*

View file

@ -232,9 +232,9 @@ typedef struct mbedtls_psa_stats_s
/** Number of slots that are not used for anything. */
size_t empty_slots;
/** Largest key id value among open keys in internal persistent storage. */
psa_app_key_id_t max_open_internal_key_id;
psa_key_id_t max_open_internal_key_id;
/** Largest key id value among open keys in secure elements. */
psa_app_key_id_t max_open_external_key_id;
psa_key_id_t max_open_external_key_id;
} mbedtls_psa_stats_t;
/** \brief Get statistics about

View file

@ -44,57 +44,40 @@
/* PSA requires several types which C99 provides in stdint.h. */
#include <stdint.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
/* Integral type representing a key handle. */
typedef uint16_t psa_key_handle_t;
/* This implementation distinguishes *application key identifiers*, which
* are the key identifiers specified by the application, from
* *key file identifiers*, which are the key identifiers that the library
* sees internally. The two types can be different if there is a remote
* call layer between the application and the library which supports
* multiple client applications that do not have access to each others'
* keys. The point of having different types is that the key file
* identifier may encode not only the key identifier specified by the
* application, but also the the identity of the application.
#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
* partition identifier.
*
* Note that this is an internal concept of the library and the remote
* call layer. The application itself never sees anything other than
* #psa_app_key_id_t with its standard definition.
* The function psa_its_identifier_of_slot() in psa_crypto_storage.c that
* translates a key identifier to a key storage file name assumes that
* mbedtls_key_owner_id_t is an 32 bits integer. This function thus needs
* reworking if mbedtls_key_owner_id_t is not defined as a 32 bits integer
* here anymore.
*/
typedef int32_t mbedtls_key_owner_id_t;
/* The application key identifier is always what the application sees as
* #psa_key_id_t. */
typedef uint32_t psa_app_key_id_t;
#if defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
#if defined(PSA_CRYPTO_SECURE)
/* Building for the PSA Crypto service on a PSA platform. */
/* A key owner is a PSA partition identifier. */
typedef int32_t psa_key_owner_id_t;
#endif
typedef struct
/** Compare two key owner identifiers.
*
* \param id1 First key owner identifier.
* \param id2 Second key owner identifier.
*
* \return Non-zero if the two key owner identifiers are equal, zero otherwise.
*/
static inline int mbedtls_key_owner_id_equal( mbedtls_key_owner_id_t id1,
mbedtls_key_owner_id_t id2 )
{
uint32_t key_id;
psa_key_owner_id_t owner;
} psa_key_file_id_t;
#define PSA_KEY_FILE_GET_KEY_ID( file_id ) ( ( file_id ).key_id )
return( id1 == id2 );
}
/* Since crypto.h is used as part of the PSA Cryptography API specification,
* it must use standard types for things like the argument of psa_open_key().
* If it wasn't for that constraint, psa_open_key() would take a
* `psa_key_file_id_t` argument. As a workaround, make `psa_key_id_t` an
* alias for `psa_key_file_id_t` when building for a multi-client service. */
typedef psa_key_file_id_t psa_key_id_t;
#define PSA_KEY_ID_INIT {0, 0}
#else /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
/* By default, a key file identifier is just the application key identifier. */
typedef psa_app_key_id_t psa_key_file_id_t;
#define PSA_KEY_FILE_GET_KEY_ID( id ) ( id )
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER */
#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
#endif /* PSA_CRYPTO_PLATFORM_H */

View file

@ -342,12 +342,12 @@ typedef struct
psa_key_type_t type;
psa_key_bits_t bits;
psa_key_lifetime_t lifetime;
psa_key_id_t id;
mbedtls_svc_key_id_t id;
psa_key_policy_t policy;
psa_key_attributes_flag_t flags;
} psa_core_key_attributes_t;
#define PSA_CORE_KEY_ATTRIBUTES_INIT {PSA_KEY_TYPE_NONE, 0, PSA_KEY_LIFETIME_VOLATILE, PSA_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0}
#define PSA_CORE_KEY_ATTRIBUTES_INIT {PSA_KEY_TYPE_NONE, 0, PSA_KEY_LIFETIME_VOLATILE, MBEDTLS_SVC_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0}
struct psa_key_attributes_s
{
@ -371,15 +371,15 @@ static inline struct psa_key_attributes_s psa_key_attributes_init( void )
return( v );
}
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
psa_key_id_t id)
static inline void psa_set_key_id( psa_key_attributes_t *attributes,
mbedtls_svc_key_id_t key )
{
attributes->core.id = id;
attributes->core.id = key;
if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE )
attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
}
static inline psa_key_id_t psa_get_key_id(
static inline mbedtls_svc_key_id_t psa_get_key_id(
const psa_key_attributes_t *attributes)
{
return( attributes->core.id );
@ -391,9 +391,8 @@ static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
attributes->core.lifetime = lifetime;
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
{
#ifdef MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
attributes->core.id.key_id = 0;
attributes->core.id.owner = 0;
#else
attributes->core.id = 0;
#endif

View file

@ -33,6 +33,8 @@
#ifndef PSA_CRYPTO_TYPES_H
#define PSA_CRYPTO_TYPES_H
#include "crypto_platform.h"
#include <stdint.h>
/** \defgroup error Error codes
@ -123,7 +125,7 @@ typedef uint32_t psa_algorithm_t;
* implementation-specific device management event occurs (for example,
* a factory reset).
*
* Persistent keys have a key identifier of type #psa_key_id_t.
* Persistent keys have a key identifier of type #mbedtls_svc_key_id_t.
* This identifier remains valid throughout the lifetime of the key,
* even if the application instance that created the key terminates.
* The application can call psa_open_key() to open a persistent key that
@ -226,15 +228,24 @@ typedef uint32_t psa_key_location_t;
* - 0 is reserved as an invalid key identifier.
* - Key identifiers outside these ranges are reserved for future use.
*/
/* Implementation-specific quirk: The Mbed Crypto library can be built as
* part of a multi-client service that exposes the PSA Crypto API in each
* client and encodes the client identity in the key id argument of functions
* such as psa_open_key(). In this build configuration, we define
* psa_key_id_t in crypto_platform.h instead of here. */
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER)
typedef uint32_t psa_key_id_t;
#define PSA_KEY_ID_INIT 0
#endif
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
typedef psa_key_id_t mbedtls_svc_key_id_t;
#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
/* Implementation-specific: The Mbed Cryptography library can be built as
* part of a multi-client service that exposes the PSA Cryptograpy API in each
* client and encodes the client identity in the key identifier argument of
* functions such as psa_open_key().
*/
typedef struct
{
psa_key_id_t key_id;
mbedtls_key_owner_id_t owner;
} mbedtls_svc_key_id_t;
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
/**@}*/

View file

@ -1656,16 +1656,83 @@
/** The minimum value for a key identifier chosen by the application.
*/
#define PSA_KEY_ID_USER_MIN ((psa_app_key_id_t)0x00000001)
#define PSA_KEY_ID_USER_MIN ((psa_key_id_t)0x00000001)
/** The maximum value for a key identifier chosen by the application.
*/
#define PSA_KEY_ID_USER_MAX ((psa_app_key_id_t)0x3fffffff)
#define PSA_KEY_ID_USER_MAX ((psa_key_id_t)0x3fffffff)
/** The minimum value for a key identifier chosen by the implementation.
*/
#define PSA_KEY_ID_VENDOR_MIN ((psa_app_key_id_t)0x40000000)
#define PSA_KEY_ID_VENDOR_MIN ((psa_key_id_t)0x40000000)
/** The maximum value for a key identifier chosen by the implementation.
*/
#define PSA_KEY_ID_VENDOR_MAX ((psa_app_key_id_t)0x7fffffff)
#define PSA_KEY_ID_VENDOR_MAX ((psa_key_id_t)0x7fffffff)
#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
#define MBEDTLS_SVC_KEY_ID_INIT ( (psa_key_id_t)0 )
#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( id )
#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( 0 )
/** Utility to initialize a key identifier at runtime.
*
* \param unused Unused parameter.
* \param key_id Identifier of the key.
*/
static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make(
unsigned int unused, psa_key_id_t key_id )
{
(void)unused;
return( key_id );
}
/** Compare two key identifiers.
*
* \param id1 First key identifier.
* \param id2 Second key identifier.
*
* \return Non-zero if the two key identifier are equal, zero otherwise.
*/
static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1,
mbedtls_svc_key_id_t id2 )
{
return( id1 == id2 );
}
#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
#define MBEDTLS_SVC_KEY_ID_INIT ( (mbedtls_svc_key_id_t){ 0, 0 } )
#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( ( id ).key_id )
#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( ( id ).owner )
/** Utility to initialize a key identifier at runtime.
*
* \param owner_id Identifier of the key owner.
* \param key_id Identifier of the key.
*/
static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make(
mbedtls_key_owner_id_t owner_id, psa_key_id_t key_id )
{
return( (mbedtls_svc_key_id_t){ .key_id = key_id,
.owner = owner_id } );
}
/** Compare two key identifiers.
*
* \param id1 First key identifier.
* \param id2 Second key identifier.
*
* \return Non-zero if the two key identifier are equal, zero otherwise.
*/
static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1,
mbedtls_svc_key_id_t id2 )
{
return( ( id1.key_id == id2.key_id ) &&
mbedtls_key_owner_id_equal( id1.owner, id2.owner ) );
}
#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
/**@}*/