From 9d75202efb8267e34e871a023539b2d9050aedf9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 9 Aug 2019 11:33:48 +0200 Subject: [PATCH] Clarify and expand the documentation of the allocate/create sequence --- include/psa/crypto_se_driver.h | 74 +++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h index 127f17b5c9..9a5d97da7a 100644 --- a/include/psa/crypto_se_driver.h +++ b/include/psa/crypto_se_driver.h @@ -811,6 +811,42 @@ typedef struct { /**@{*/ /** \brief A function that allocates a slot for a key. + * + * To create a key in a specific slot in a secure element, the core + * first calls this function to determine a valid slot number, + * then calls a function to create the key material in that slot. + * For example, in nominal conditions (that is, if no error occurs), + * the effect of a call to psa_import_key() with a lifetime that places + * the key in a secure element is the following: + * -# The core calls psa_drv_se_key_management_t::p_allocate + * (or in some implementations + * psa_drv_se_key_management_t::p_validate_slot_number). The driver + * selects (or validates) a suitable slot number given the key attributes + * and the state of the secure element. + * -# The core calls psa_drv_se_key_management_t::p_import to import + * the key material in the selected slot. + * + * Other key creation methods lead to similar sequences. For example, the + * sequence for psa_generate_key() is the same except that the second step + * is a call to psa_drv_se_key_management_t::p_generate. + * + * In case of errors, other behaviors are possible. + * - If the PSA Cryptography subsystem dies after the first step, + * for example because the device has lost power abruptly, + * the second step may never happen, or may happen after a reset + * and re-initialization. Alternatively, after a reset and + * re-initialization, the core may call + * psa_drv_se_key_management_t::p_destroy on the slot number that + * was allocated (or validated) instead of calling a key creation function. + * - If an error occurs, the core may call + * psa_drv_se_key_management_t::p_destroy on the slot number that + * was allocated (or validated) instead of calling a key creation function. + * + * Errors and system resets also have an impact on the driver's persistent + * data. If a reset happens before the overall key creation process is + * completed (before or after the second step above), it is unspecified + * whether the persistent data after the reset is identical to what it + * was before or after the call to `p_allocate` (or `p_validate_slot_number`). * * \param[in,out] drv_context The driver context structure. * \param[in,out] persistent_data A pointer to the persistent data @@ -836,6 +872,18 @@ typedef psa_status_t (*psa_drv_se_allocate_key_t)( /** \brief A function that determines whether a slot number is valid * for a key. * + * To create a key in a specific slot in a secure element, the core + * first calls this function to validate the choice of slot number, + * then calls a function to create the key material in that slot. + * See the documentation of #psa_drv_se_allocate_key_t for more details. + * + * As of the PSA Cryptography API specification version 1.0, there is no way + * for applications to trigger a call to this function. However some + * implementations offer the capability to create or declare a key in + * a specific slot via implementation-specific means, generally for the + * sake of initial device provisioning or onboarding. Such a mechanism may + * be added to a future version of the PSA Cryptography API specification. + * * \param[in,out] drv_context The driver context structure. * \param[in] attributes Attributes of the key. * \param[in] key_slot Slot where the key is to be stored. @@ -1001,31 +1049,9 @@ typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_drv_se_context_t *drv_cont * If one of the functions is not implemented, it should be set to NULL. */ typedef struct { - /** Function that allocates a slot for a key. - * - * The core calls this function to determine a slot number, then - * calls the actual creation function (such as - * psa_drv_se_key_management_t::p_import or - * psa_drv_se_key_management_t::p_generate). - * - * If this function succeeds, the next call that the core makes to the - * driver is either the creation function or - * psa_drv_se_key_management_t::p_destroy. Note that - * if the platform is reset after this function returns, the core - * may either subsequently call - * psa_drv_se_key_management_t::p_destroy or may behave as if the - * last call to this function had not taken place. - */ + /** Function that allocates a slot for a key. */ psa_drv_se_allocate_key_t p_allocate; - /** Function that checks the validity of a slot for a key. - * - * The core calls this function instead of - * psa_drv_se_key_management_t::p_allocate to create - * a key in a specific slot. It then calls the actual creation function - * (such as psa_drv_se_key_management_t::p_import or - * psa_drv_se_key_management_t::p_generate) or - * psa_drv_se_key_management_t::p_destroy. - */ + /** Function that checks the validity of a slot for a key. */ psa_drv_se_validate_slot_number_t p_validate_slot_number; /** Function that performs a key import operation */ psa_drv_se_import_key_t p_import;