Driver context manipulation functions
Create the driver context when registering the driver.
Implement some helper functions to access driver information.
diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c
index 70e3a16..b95b2a5 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 <assert.h>
+#include <stdint.h>
#include <string.h>
+#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_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 @@
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 @@
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 88b0127..a9951e6 100644
--- a/library/psa_crypto_se.h
+++ b/library/psa_crypto_se.h
@@ -45,11 +45,30 @@
/** 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 @@
* \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 */