Skip to content

Commit 30e13eb

Browse files
Merge pull request #211 from gilles-peskine-arm/psa-se_driver-generate_key
Add hooks for generate and sign in a secure element
2 parents 5a2d152 + 8df72f2 commit 30e13eb

File tree

4 files changed

+685
-134
lines changed

4 files changed

+685
-134
lines changed

include/psa/crypto_se_driver.h

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -956,15 +956,21 @@ typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
956956
* documentation of psa_export_key() for the format for each key type.
957957
*
958958
* \param[in,out] drv_context The driver context structure.
959-
* \param[in] key_slot Slot where the key will be stored
959+
* \param key_slot Slot where the key will be stored.
960960
* This must be a valid slot for a key of the
961961
* chosen type. It must be unoccupied.
962-
* \param[in] lifetime The required lifetime of the key storage
963-
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
964-
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
965-
* \param[in] usage The allowed uses of the key
966-
* \param[in] p_data Buffer containing the key data
967-
* \param[in] data_length Size of the `data` buffer in bytes
962+
* \param[in] attributes The key attributes, including the lifetime,
963+
* the key type and the usage policy.
964+
* Drivers should not access the key size stored
965+
* in the attributes: it may not match the
966+
* data passed in \p data.
967+
* Drivers can call psa_get_key_lifetime(),
968+
* psa_get_key_type(),
969+
* psa_get_key_usage_flags() and
970+
* psa_get_key_algorithm() to access this
971+
* information.
972+
* \param[in] data Buffer containing the key data.
973+
* \param[in] data_length Size of the \p data buffer in bytes.
968974
* \param[out] bits On success, the key size in bits. The driver
969975
* must determine this value after parsing the
970976
* key according to the key type.
@@ -973,15 +979,13 @@ typedef psa_status_t (*psa_drv_se_validate_slot_number_t)(
973979
* \retval #PSA_SUCCESS
974980
* Success.
975981
*/
976-
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_drv_se_context_t *drv_context,
977-
psa_key_slot_number_t key_slot,
978-
psa_key_lifetime_t lifetime,
979-
psa_key_type_t type,
980-
psa_algorithm_t algorithm,
981-
psa_key_usage_t usage,
982-
const uint8_t *p_data,
983-
size_t data_length,
984-
size_t *bits);
982+
typedef psa_status_t (*psa_drv_se_import_key_t)(
983+
psa_drv_se_context_t *drv_context,
984+
psa_key_slot_number_t key_slot,
985+
const psa_key_attributes_t *attributes,
986+
const uint8_t *data,
987+
size_t data_length,
988+
size_t *bits);
985989

986990
/**
987991
* \brief A function that destroys a secure element key and restore the slot to
@@ -1048,41 +1052,51 @@ typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_contex
10481052
* element
10491053
*
10501054
* If \p type is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) = 1),
1051-
* the public component of the generated key will be placed in `p_pubkey_out`.
1052-
* The format of the public key information will match the format specified for
1053-
* the psa_export_key() function for the key type.
1055+
* the driver may export the public key at the time of generation,
1056+
* in the format documented for psa_export_public_key() by writing it
1057+
* to the \p pubkey buffer.
1058+
* This is optional, intended for secure elements that output the
1059+
* public key at generation time and that cannot export the public key
1060+
* later. Drivers that do not need this feature should leave
1061+
* \p *pubkey_length set to 0 and should
1062+
* implement the psa_drv_key_management_t::p_export_public function.
1063+
* Some implementations do not support this feature, in which case
1064+
* \p pubkey is \c NULL and \p pubkey_size is 0.
10541065
*
10551066
* \param[in,out] drv_context The driver context structure.
1056-
* \param[in] key_slot Slot where the generated key will be placed
1057-
* \param[in] type The type of the key to be generated
1058-
* \param[in] usage The prescribed usage of the generated key
1059-
* Note: Not all Secure Elements support the same
1060-
* restrictions that PSA Crypto does (and vice
1061-
* versa).
1062-
* Driver developers should endeavor to match the
1063-
* usages as close as possible.
1064-
* \param[in] bits The size in bits of the key to be generated.
1065-
* \param[in] extra Extra parameters for key generation. The
1066-
* interpretation of this parameter should match
1067-
* the interpretation in the `extra` parameter is
1068-
* the `psa_generate_key` function
1069-
* \param[in] extra_size The size in bytes of the \p extra buffer
1070-
* \param[out] p_pubkey_out The buffer where the public key information will
1071-
* be placed
1072-
* \param[in] pubkey_out_size The size in bytes of the `p_pubkey_out` buffer
1073-
* \param[out] p_pubkey_length Upon successful completion, will contain the
1074-
* size of the data placed in `p_pubkey_out`.
1067+
* \param key_slot Slot where the key will be stored.
1068+
* This must be a valid slot for a key of the
1069+
* chosen type. It must be unoccupied.
1070+
* \param[in] attributes The key attributes, including the lifetime,
1071+
* the key type and size, and the usage policy.
1072+
* Drivers can call psa_get_key_lifetime(),
1073+
* psa_get_key_type(), psa_get_key_bits(),
1074+
* psa_get_key_usage_flags() and
1075+
* psa_get_key_algorithm() to access this
1076+
* information.
1077+
* \param[out] pubkey A buffer where the driver can write the
1078+
* public key, when generating an asymmetric
1079+
* key pair.
1080+
* This is \c NULL when generating a symmetric
1081+
* key or if the core does not support
1082+
* exporting the public key at generation time.
1083+
* \param pubkey_size The size of the `pubkey` buffer in bytes.
1084+
* This is 0 when generating a symmetric
1085+
* key or if the core does not support
1086+
* exporting the public key at generation time.
1087+
* \param[out] pubkey_length On entry, this is always 0.
1088+
* On success, the number of bytes written to
1089+
* \p pubkey. If this is 0 or unchanged on return,
1090+
* the core will not read the \p pubkey buffer,
1091+
* and will instead call the driver's
1092+
* psa_drv_key_management_t::p_export_public
1093+
* function to export the public key when needed.
10751094
*/
1076-
typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_drv_se_context_t *drv_context,
1077-
psa_key_slot_number_t key_slot,
1078-
psa_key_type_t type,
1079-
psa_key_usage_t usage,
1080-
size_t bits,
1081-
const void *extra,
1082-
size_t extra_size,
1083-
uint8_t *p_pubkey_out,
1084-
size_t pubkey_out_size,
1085-
size_t *p_pubkey_length);
1095+
typedef psa_status_t (*psa_drv_se_generate_key_t)(
1096+
psa_drv_se_context_t *drv_context,
1097+
psa_key_slot_number_t key_slot,
1098+
const psa_key_attributes_t *attributes,
1099+
uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length);
10861100

10871101
/**
10881102
* \brief A struct containing all of the function pointers needed to for secure

library/psa_crypto.c

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,10 +1827,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes,
18271827
}
18281828
status = drv->key_management->p_import(
18291829
psa_get_se_driver_context( driver ),
1830-
slot->data.se.slot_number,
1831-
slot->attr.lifetime, slot->attr.type,
1832-
slot->attr.policy.alg, slot->attr.policy.usage,
1833-
data, data_length,
1830+
slot->data.se.slot_number, attributes, data, data_length,
18341831
&bits );
18351832
if( status != PSA_SUCCESS )
18361833
goto exit;
@@ -3334,10 +3331,14 @@ psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
33343331
{
33353332
psa_key_slot_t *slot;
33363333
psa_status_t status;
3334+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3335+
const psa_drv_se_t *drv;
3336+
psa_drv_se_context_t *drv_context;
3337+
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
33373338

33383339
*signature_length = signature_size;
33393340

3340-
status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
3341+
status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg );
33413342
if( status != PSA_SUCCESS )
33423343
goto exit;
33433344
if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) )
@@ -3346,6 +3347,24 @@ psa_status_t psa_asymmetric_sign( psa_key_handle_t handle,
33463347
goto exit;
33473348
}
33483349

3350+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3351+
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
3352+
{
3353+
if( drv->asymmetric == NULL ||
3354+
drv->asymmetric->p_sign == NULL )
3355+
{
3356+
status = PSA_ERROR_NOT_SUPPORTED;
3357+
goto exit;
3358+
}
3359+
status = drv->asymmetric->p_sign( drv_context,
3360+
slot->data.se.slot_number,
3361+
alg,
3362+
hash, hash_length,
3363+
signature, signature_size,
3364+
signature_length );
3365+
}
3366+
else
3367+
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
33493368
#if defined(MBEDTLS_RSA_C)
33503369
if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR )
33513370
{
@@ -3409,11 +3428,29 @@ psa_status_t psa_asymmetric_verify( psa_key_handle_t handle,
34093428
{
34103429
psa_key_slot_t *slot;
34113430
psa_status_t status;
3431+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3432+
const psa_drv_se_t *drv;
3433+
psa_drv_se_context_t *drv_context;
3434+
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
34123435

3413-
status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
3436+
status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg );
34143437
if( status != PSA_SUCCESS )
34153438
return( status );
34163439

3440+
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
3441+
if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) )
3442+
{
3443+
if( drv->asymmetric == NULL ||
3444+
drv->asymmetric->p_verify == NULL )
3445+
return( PSA_ERROR_NOT_SUPPORTED );
3446+
return( drv->asymmetric->p_verify( drv_context,
3447+
slot->data.se.slot_number,
3448+
alg,
3449+
hash, hash_length,
3450+
signature, signature_length ) );
3451+
}
3452+
else
3453+
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
34173454
#if defined(MBEDTLS_RSA_C)
34183455
if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) )
34193456
{
@@ -5947,21 +5984,37 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes,
59475984
psa_status_t status;
59485985
psa_key_slot_t *slot = NULL;
59495986
psa_se_drv_table_entry_t *driver = NULL;
5987+
59505988
status = psa_start_key_creation( PSA_KEY_CREATION_GENERATE,
59515989
attributes, handle, &slot, &driver );
5990+
if( status != PSA_SUCCESS )
5991+
goto exit;
5992+
59525993
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
59535994
if( driver != NULL )
59545995
{
5955-
/* Generating a key in a secure element is not implemented yet. */
5956-
status = PSA_ERROR_NOT_SUPPORTED;
5996+
const psa_drv_se_t *drv = psa_get_se_driver_methods( driver );
5997+
size_t pubkey_length = 0; /* We don't support this feature yet */
5998+
if( drv->key_management == NULL ||
5999+
drv->key_management->p_generate == NULL )
6000+
{
6001+
status = PSA_ERROR_NOT_SUPPORTED;
6002+
goto exit;
6003+
}
6004+
status = drv->key_management->p_generate(
6005+
psa_get_se_driver_context( driver ),
6006+
slot->data.se.slot_number, attributes,
6007+
NULL, 0, &pubkey_length );
59576008
}
6009+
else
59586010
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
5959-
if( status == PSA_SUCCESS )
59606011
{
59616012
status = psa_generate_key_internal(
59626013
slot, attributes->core.bits,
59636014
attributes->domain_parameters, attributes->domain_parameters_size );
59646015
}
6016+
6017+
exit:
59656018
if( status == PSA_SUCCESS )
59666019
status = psa_finish_key_creation( slot, driver );
59676020
if( status != PSA_SUCCESS )

0 commit comments

Comments
 (0)