From 5243a202c3e1d9193e02d2725fb516aa179159bc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 12 Jul 2019 23:38:19 +0200 Subject: [PATCH] Driver context manipulation functions Create the driver context when registering the driver. Implement some helper functions to access driver information. --- library/psa_crypto_se.c | 102 ++++++++++++++++++++++++++++++++++++---- library/psa_crypto_se.h | 61 +++++++++++++++++++----- 2 files changed, 141 insertions(+), 22 deletions(-) diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c index 70e3a1680..b95b2a5d5 100644 --- a/library/psa_crypto_se.c +++ b/library/psa_crypto_se.c @@ -28,23 +28,49 @@ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) #include +#include #include +#include "psa/crypto_se_driver.h" + #include "psa_crypto_se.h" +#include "mbedtls/platform.h" +#if !defined(MBEDTLS_PLATFORM_C) +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + + + /****************************************************************/ /* Driver lookup */ /****************************************************************/ +/* This structure is identical to psa_drv_se_context_t declared in + * `crypto_se_driver.h`, except that some parts are writable here + * (non-const, or pointer to non-const). */ +typedef struct +{ + void *persistent_data; + size_t persistent_data_size; + uintptr_t transient_data; +} psa_drv_se_internal_context_t; + typedef struct psa_se_drv_table_entry_s { psa_key_lifetime_t lifetime; const psa_drv_se_t *methods; + union + { + psa_drv_se_internal_context_t internal; + psa_drv_se_context_t context; + }; } psa_se_drv_table_entry_t; static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS]; -const psa_se_drv_table_entry_t *psa_get_se_driver_entry( +psa_se_drv_table_entry_t *psa_get_se_driver_entry( psa_key_lifetime_t lifetime ) { size_t i; @@ -59,20 +85,50 @@ const psa_se_drv_table_entry_t *psa_get_se_driver_entry( } const psa_drv_se_t *psa_get_se_driver_methods( - const psa_se_drv_table_entry_t *drv ) + const psa_se_drv_table_entry_t *driver ) { - return( drv->methods ); + return( driver->methods ); } -const psa_drv_se_t *psa_get_se_driver( psa_key_lifetime_t lifetime ) +psa_drv_se_context_t *psa_get_se_driver_context( + psa_se_drv_table_entry_t *driver ) { - const psa_se_drv_table_entry_t *drv = psa_get_se_driver_entry( lifetime ); - if( drv == NULL ) - return( NULL ); - else - return( drv->methods ); + return( &driver->context ); } +int psa_get_se_driver( psa_key_lifetime_t lifetime, + const psa_drv_se_t **p_methods, + psa_drv_se_context_t **p_drv_context) +{ + psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime ); + if( p_methods != NULL ) + *p_methods = ( driver ? driver->methods : NULL ); + if( p_drv_context != NULL ) + *p_drv_context = ( driver ? &driver->context : NULL ); + return( driver != NULL ); +} + + + +/****************************************************************/ +/* Persistent data management */ +/****************************************************************/ + +psa_status_t psa_load_se_persistent_data( + const psa_se_drv_table_entry_t *driver ) +{ + /*TODO*/ + (void) driver; + return( PSA_SUCCESS ); +} + +psa_status_t psa_save_se_persistent_data( + const psa_se_drv_table_entry_t *driver ) +{ + /*TODO*/ + (void) driver; + return( PSA_SUCCESS ); +} @@ -85,6 +141,7 @@ psa_status_t psa_register_se_driver( const psa_drv_se_t *methods) { size_t i; + psa_status_t status; if( methods->hal_version != PSA_DRV_SE_HAL_VERSION ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -115,11 +172,38 @@ psa_status_t psa_register_se_driver( driver_table[i].lifetime = lifetime; driver_table[i].methods = methods; + + if( methods->persistent_data_size != 0 ) + { + driver_table[i].internal.persistent_data = + mbedtls_calloc( 1, methods->persistent_data_size ); + if( driver_table[i].internal.persistent_data == NULL ) + { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + goto error; + } + status = psa_load_se_persistent_data( &driver_table[i] ); + if( status != PSA_SUCCESS ) + goto error; + } + driver_table[i].internal.persistent_data_size = + methods->persistent_data_size; + return( PSA_SUCCESS ); + +error: + memset( &driver_table[i], 0, sizeof( driver_table[i] ) ); + return( status ); } void psa_unregister_all_se_drivers( void ) { + size_t i; + for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ ) + { + if( driver_table[i].internal.persistent_data != NULL ) + mbedtls_free( driver_table[i].internal.persistent_data ); + } memset( driver_table, 0, sizeof( driver_table ) ); } diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h index 88b0127c6..a9951e661 100644 --- a/library/psa_crypto_se.h +++ b/library/psa_crypto_se.h @@ -45,11 +45,30 @@ void psa_unregister_all_se_drivers( void ); /** A structure that describes a registered secure element driver. * * A secure element driver table entry contains a pointer to the - * driver's method table and a pointer to the driver's slot usage - * structure. + * driver's method table as well as the driver context structure. */ typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t; +/** Return the secure element driver information for a lifetime value. + * + * \param lifetime The lifetime value to query. + * \param[out] p_methods On output, if there is a driver, + * \c *methods points to its method table. + * Otherwise \c *methods is \c NULL. + * \param[out] p_drv_context On output, if there is a driver, + * \c *drv_context points to its context + * structure. + * Otherwise \c *drv_context is \c NULL. + * + * \retval 1 + * \p lifetime corresponds to a registered driver. + * \retval 0 + * \p lifetime does not correspond to a registered driver. + */ +int psa_get_se_driver( psa_key_lifetime_t lifetime, + const psa_drv_se_t **p_methods, + psa_drv_se_context_t **p_drv_context); + /** Return the secure element driver table entry for a lifetime value. * * \param lifetime The lifetime value to query. @@ -57,27 +76,43 @@ typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t; * \return The driver table entry for \p lifetime, or * \p NULL if \p lifetime does not correspond to a registered driver. */ -const psa_se_drv_table_entry_t *psa_get_se_driver_entry( +psa_se_drv_table_entry_t *psa_get_se_driver_entry( psa_key_lifetime_t lifetime ); /** Return the method table for a secure element driver. * - * \param[in] drv The driver table entry to access. + * \param[in] driver The driver table entry to access, or \c NULL. * - * \return The driver table entry for \p lifetime, or - * \p NULL if \p lifetime does not correspond to a registered driver. + * \return The driver's method table. + * \c NULL if \p driver is \c NULL. */ const psa_drv_se_t *psa_get_se_driver_methods( - const psa_se_drv_table_entry_t *drv ); + const psa_se_drv_table_entry_t *driver ); -/** Return the secure element driver method table for a lifetime value. +/** Return the context of a secure element driver. * - * \param lifetime The lifetime value to query. + * \param[in] driver The driver table entry to access, or \c NULL. * - * \return The driver method table for \p lifetime, or - * \p NULL if \p lifetime does not correspond to a registered driver. + * \return A pointer to the driver context. + * \c NULL if \p driver is \c NULL. */ -const psa_drv_se_t *psa_get_se_driver( - psa_key_lifetime_t lifetime ); +psa_drv_se_context_t *psa_get_se_driver_context( + psa_se_drv_table_entry_t *driver ); + +/** Load the persistent data of a secure element driver. + * + * \param driver The driver table entry containing the persistent + * data to load from storage. + */ +psa_status_t psa_load_se_persistent_data( + const psa_se_drv_table_entry_t *driver ); + +/** Save the persistent data of a secure element driver. + * + * \param[in] driver The driver table entry containing the persistent + * data to save to storage. + */ +psa_status_t psa_save_se_persistent_data( + const psa_se_drv_table_entry_t *driver ); #endif /* PSA_CRYPTO_SE_H */