diff --git a/ChangeLog.d/add-iop-psa-generate-key.txt b/ChangeLog.d/add-iop-psa-generate-key.txt new file mode 100644 index 000000000000..336abd31774f --- /dev/null +++ b/ChangeLog.d/add-iop-psa-generate-key.txt @@ -0,0 +1,4 @@ +Features + * Add new psa key agreements APIs to generate private key + in an interruptible manner and return an identifier for + the newly created key. diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index d3b7d6fb312e..008049922ee9 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -835,6 +835,108 @@ static inline psa_status_t psa_driver_wrapper_generate_key( return( status ); } + +static inline psa_status_t psa_driver_wrapper_generate_key_get_num_ops( + psa_generate_key_iop_t *operation) +{ + switch( operation->id ) + { + /* If uninitialised, return 0, as no work can have been done. */ + case 0: + return 0; + + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return(mbedtls_psa_generate_key_get_num_ops(&operation->ctx.mbedtls_ctx)); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + return 0; +} + +static inline psa_status_t psa_driver_wrapper_generate_key_setup( + psa_generate_key_iop_t *operation, + const psa_key_attributes_t *attributes) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( + psa_get_key_lifetime(attributes) ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + + +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + /* Fell through, meaning no accelerator supports this operation */ + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + status = mbedtls_psa_generate_key_setup(&operation->ctx.mbedtls_ctx, + attributes); + break; + + /* Add cases for opaque driver here */ + + default: + /* Key is declared with a lifetime not known to us */ + status = PSA_ERROR_INVALID_ARGUMENT; + break; + } + return( status ); +} + +static inline psa_status_t psa_driver_wrapper_generate_key_complete( + psa_generate_key_iop_t *operation, + uint8_t *key_output, + size_t *key_len) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + switch( operation->id ) + { + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + status = mbedtls_psa_generate_key_complete(&operation->ctx.mbedtls_ctx, + key_output, key_len); + break; + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + + +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + status = PSA_ERROR_INVALID_ARGUMENT; + break; + } + return( status ); +} + +static inline psa_status_t psa_driver_wrapper_generate_key_abort( + psa_generate_key_iop_t *operation) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + switch( operation->id ) + { + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + status = mbedtls_psa_generate_key_abort(&operation->ctx.mbedtls_ctx); + break; + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) + + +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + status = PSA_ERROR_INVALID_ARGUMENT; + break; + } + return( status ); +} + + static inline psa_status_t psa_driver_wrapper_import_key( const psa_key_attributes_t *attributes, const uint8_t *data, diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h index 7ab2bea6b958..ef115f5bd84a 100644 --- a/tests/include/test/psa_test_wrappers.h +++ b/tests/include/test/psa_test_wrappers.h @@ -370,7 +370,7 @@ psa_status_t mbedtls_test_wrap_psa_generate_key_iop_abort( psa_status_t mbedtls_test_wrap_psa_generate_key_iop_complete( psa_generate_key_iop_t *arg0_operation, - psa_key_id_t *arg1_key); + mbedtls_svc_key_id_t *arg1_key); #define psa_generate_key_iop_complete(arg0_operation, arg1_key) \ mbedtls_test_wrap_psa_generate_key_iop_complete(arg0_operation, arg1_key) diff --git a/tests/psa-client-server/psasim/src/psa_sim_serialise.c b/tests/psa-client-server/psasim/src/psa_sim_serialise.c index e5c7225c845b..1aeae791ed45 100644 --- a/tests/psa-client-server/psasim/src/psa_sim_serialise.c +++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.c @@ -1624,6 +1624,42 @@ int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, return 1; } +size_t psasim_serialise_psa_generate_key_iop_t_needs( + psa_generate_key_iop_t value) +{ + return sizeof(value); +} + +int psasim_serialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t value) +{ + if (*remaining < sizeof(value)) { + return 0; + } + + memcpy(*pos, &value, sizeof(value)); + *pos += sizeof(value); + + return 1; +} + +int psasim_deserialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t *value) +{ + if (*remaining < sizeof(*value)) { + return 0; + } + + memcpy(value, *pos, sizeof(*value)); + + *pos += sizeof(*value); + *remaining -= sizeof(*value); + + return 1; +} + void psa_sim_serialize_reset(void) { memset(hash_operation_handles, 0, diff --git a/tests/psa-client-server/psasim/src/psa_sim_serialise.h b/tests/psa-client-server/psasim/src/psa_sim_serialise.h index 523ce8028bdb..9a49887ac0ac 100644 --- a/tests/psa-client-server/psasim/src/psa_sim_serialise.h +++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.h @@ -1301,3 +1301,46 @@ int psasim_serialise_mbedtls_svc_key_id_t(uint8_t **pos, int psasim_deserialise_mbedtls_svc_key_id_t(uint8_t **pos, size_t *remaining, mbedtls_svc_key_id_t *value); + +/** Return how much buffer space is needed by \c psasim_serialise_psa_generate_key_iop_t() + * to serialise a `psa_generate_key_iop_t`. + * + * \param value The value that will be serialised into the buffer + * (needed in case some serialisations are value- + * dependent). + * + * \return The number of bytes needed in the buffer by + * \c psasim_serialise_psa_generate_key_iop_t() to serialise + * the given value. + */ +size_t psasim_serialise_psa_generate_key_iop_t_needs( + psa_generate_key_iop_t value); + +/** Serialise a `psa_generate_key_iop_t` into a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value The value to serialise into the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_serialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t value); + +/** Deserialise a `psa_generate_key_iop_t` from a buffer. + * + * \param pos[in,out] Pointer to a `uint8_t *` holding current position + * in the buffer. + * \param remaining[in,out] Pointer to a `size_t` holding number of bytes + * remaining in the buffer. + * \param value Pointer to a `psa_generate_key_iop_t` to receive the value + * deserialised from the buffer. + * + * \return \c 1 on success ("okay"), \c 0 on error. + */ +int psasim_deserialise_psa_generate_key_iop_t(uint8_t **pos, + size_t *remaining, + psa_generate_key_iop_t *value); diff --git a/tests/psa-client-server/psasim/src/psa_sim_serialise.pl b/tests/psa-client-server/psasim/src/psa_sim_serialise.pl index 31c93aeb20c6..49fb0658f5f4 100755 --- a/tests/psa-client-server/psasim/src/psa_sim_serialise.pl +++ b/tests/psa-client-server/psasim/src/psa_sim_serialise.pl @@ -48,7 +48,8 @@ psa_key_derivation_operation_t psa_sign_hash_interruptible_operation_t psa_verify_hash_interruptible_operation_t - mbedtls_svc_key_id_t); + mbedtls_svc_key_id_t + psa_generate_key_iop_t); grep(s/-/ /g, @types); diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 6e42a8bba6a1..b5419b9cd428 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -633,7 +633,7 @@ psa_status_t mbedtls_test_wrap_psa_generate_key_iop_abort( /* Wrapper for psa_generate_key_iop_complete */ psa_status_t mbedtls_test_wrap_psa_generate_key_iop_complete( psa_generate_key_iop_t *arg0_operation, - psa_key_id_t *arg1_key) + mbedtls_svc_key_id_t *arg1_key) { psa_status_t status = (psa_generate_key_iop_complete)(arg0_operation, arg1_key); return status; diff --git a/tf-psa-crypto/core/psa_crypto.c b/tf-psa-crypto/core/psa_crypto.c index d1c93fd21511..799712bd14e1 100644 --- a/tf-psa-crypto/core/psa_crypto.c +++ b/tf-psa-crypto/core/psa_crypto.c @@ -8085,6 +8085,113 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, key); } + +uint32_t psa_generate_key_iop_get_num_ops( + psa_generate_key_iop_t *operation) +{ +#if defined(MBEDTLS_ECP_RESTARTABLE) + return psa_driver_wrapper_generate_key_get_num_ops(operation); +#else + (void) operation; + return 0; +#endif +} + +psa_status_t psa_generate_key_iop_setup( + psa_generate_key_iop_t *operation, + const psa_key_attributes_t *attributes) +{ +#if defined(MBEDTLS_ECP_RESTARTABLE) + psa_status_t status; + psa_key_type_t type; + + if (operation->id != 0 || operation->error_occurred) { + return PSA_ERROR_BAD_STATE; + } + + type = psa_get_key_type(attributes); + + if (!PSA_KEY_TYPE_IS_ECC(type)) { + operation->error_occurred = 1; + return PSA_ERROR_NOT_SUPPORTED; + } + + if (psa_get_key_bits(attributes) == 0) { + operation->error_occurred = 1; + return PSA_ERROR_INVALID_ARGUMENT; + } + + + if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) { + operation->error_occurred = 1; + return PSA_ERROR_INVALID_ARGUMENT; + } + + operation->attributes = attributes; + + status = psa_driver_wrapper_generate_key_setup(operation, attributes); + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + } + + return status; +#else + (void) operation; + (void) attributes; + return PSA_ERROR_NOT_SUPPORTED; +#endif +} + +psa_status_t psa_generate_key_iop_complete( + psa_generate_key_iop_t *operation, + mbedtls_svc_key_id_t *key) +{ +#if defined(MBEDTLS_ECP_RESTARTABLE) + psa_status_t status; + uint8_t key_data[MBEDTLS_ECP_MAX_BYTES] = { 0 }; + size_t key_len = 0; + + if (operation->id == 0 || operation->error_occurred) { + return PSA_ERROR_BAD_STATE; + } + + status = psa_driver_wrapper_generate_key_complete(operation, key_data, &key_len); + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + return status; + } + + status = psa_import_key(operation->attributes, key_data, key_len, key); + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + } + + mbedtls_platform_zeroize(key_data, MBEDTLS_ECP_MAX_BYTES); + return status; +#else + (void) operation; + (void) key; + return PSA_ERROR_NOT_SUPPORTED; +#endif +} + +psa_status_t psa_generate_key_iop_abort( + psa_generate_key_iop_t *operation) +{ +#if defined(MBEDTLS_ECP_RESTARTABLE) + psa_status_t status; + + status = psa_driver_wrapper_generate_key_abort(operation); + operation->error_occurred = 0; + operation->attributes = NULL; + return status; +#else + (void) operation; + return PSA_ERROR_NOT_SUPPORTED; +#endif +} + + /****************************************************************/ /* Module setup */ /****************************************************************/ diff --git a/tf-psa-crypto/core/psa_crypto_core.h b/tf-psa-crypto/core/psa_crypto_core.h index 21e7559f01c3..d7f2c9931def 100644 --- a/tf-psa-crypto/core/psa_crypto_core.h +++ b/tf-psa-crypto/core/psa_crypto_core.h @@ -431,6 +431,91 @@ psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes, size_t key_buffer_size, size_t *key_buffer_length); +/** + * \brief Get the total number of ops that a key generation operation has taken + * Since it's start. + * + * \note The signature of this function is that of a PSA driver + * generate_key_get_num_ops entry point. This function behaves as an + * generate_key_get_num_ops entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in] operation The \c mbedtls_psa_generate_key_iop_operation_t to use. + * This must be initialized first. + * \return Total number of operations. + */ +uint32_t mbedtls_psa_generate_key_get_num_ops( + mbedtls_psa_generate_key_iop_operation_t *operation); + +/** + * \brief Setup a new interruptible key generation operation. + * + * \note The signature of this function is that of a PSA driver + * generate_key_setup entry point. This function behaves as a + * generate_key_setup entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * \param[in] operation The \c mbedtls_psa_generate_key_iop_operation_t to use. + * This must be initialized first. + * \param[in] attributes The desired attributes of the generated key. + * + * \retval #PSA_SUCCESS + * The operation started successfully - call \c mbedtls_psa_generate_key_complete() + * with the same context to complete the operation. + * * \retval #PSA_ERROR_NOT_SUPPORTED + * Either no internal interruptible operations are + * currently supported, or the key attributes are not unsupported. + * * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * There was insufficient memory to load the key representation. + * + */ +psa_status_t mbedtls_psa_generate_key_setup( + mbedtls_psa_generate_key_iop_operation_t *operation, + const psa_key_attributes_t *attributes); + +/** + * \brief Continue and eventually complete a key generation operation. + * + * \note The signature of this function is that of a PSA driver + * generate_key_complete entry point. This function behaves as a + * generate_key_complete entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in] operation The \c mbedtls_psa_generate_key_iop_operation_t to use. + * This must be initialized first. + * \param[out] key_output The buffer to which the generated key + * is to be written. + * \param[out] key_len On success, the number of bytes that make + * up the returned key output. + * \retval #PSA_SUCCESS + * The key was generated successfully. + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * + */ +psa_status_t mbedtls_psa_generate_key_complete( + mbedtls_psa_generate_key_iop_operation_t *operation, + uint8_t *key_output, + size_t *key_len); + +/** + * \brief Abort a key generation operation. + * + * \note The signature of this function is that of a PSA driver + * generate_key_abort entry point. This function behaves as a + * generate_key_abort entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in] operation The \c mbedtls_psa_generate_key_iop_operation_t to abort. + * This must be initialized first. + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + * + */ +psa_status_t mbedtls_psa_generate_key_abort( + mbedtls_psa_generate_key_iop_operation_t *operation); + + /** Sign a message with a private key. For hash-and-sign algorithms, * this includes the hashing step. * diff --git a/tf-psa-crypto/core/psa_crypto_ecp.c b/tf-psa-crypto/core/psa_crypto_ecp.c index 749e11be03b2..b55dd2ea4200 100644 --- a/tf-psa-crypto/core/psa_crypto_ecp.c +++ b/tf-psa-crypto/core/psa_crypto_ecp.c @@ -596,39 +596,83 @@ psa_status_t mbedtls_psa_key_agreement_ecdh( /* Interruptible ECC Key Generation */ /****************************************************************/ -uint32_t psa_generate_key_iop_get_num_ops( - psa_generate_key_iop_t *operation) +uint32_t mbedtls_psa_generate_key_get_num_ops( + mbedtls_psa_generate_key_iop_operation_t *operation) { +#if defined(MBEDTLS_ECP_C) + return operation->num_ops; +#else (void) operation; return 0; +#endif } -psa_status_t psa_generate_key_iop_setup( - psa_generate_key_iop_t *operation, +psa_status_t mbedtls_psa_generate_key_setup( + mbedtls_psa_generate_key_iop_operation_t *operation, const psa_key_attributes_t *attributes) { +#if defined(MBEDTLS_ECP_C) + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( + psa_get_key_type(attributes)); + mbedtls_ecp_group_id grp_id = + mbedtls_ecc_group_from_psa(curve, psa_get_key_bits(attributes)); + if (grp_id == MBEDTLS_ECP_DP_NONE) { + return PSA_ERROR_NOT_SUPPORTED; + } + + mbedtls_ecp_keypair_init(&operation->ecp); + + status = mbedtls_ecp_group_load(&operation->ecp.grp, grp_id); + + return mbedtls_to_psa_error(status); +#else (void) operation; (void) attributes; - return PSA_ERROR_NOT_SUPPORTED; +#endif } -psa_status_t psa_generate_key_iop_complete( - psa_generate_key_iop_t *operation, - psa_key_id_t *key) +psa_status_t mbedtls_psa_generate_key_complete( + mbedtls_psa_generate_key_iop_operation_t *operation, + uint8_t *key_output, + size_t *key_len) { - (void) operation; - (void) key; +#if defined(MBEDTLS_ECP_C) + *key_len = 0; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + status = mbedtls_ecp_gen_privkey(&operation->ecp.grp, &operation->ecp.d, + mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE); + + if (status) { + return mbedtls_to_psa_error(status); + } + operation->num_ops = 1; + *key_len = mbedtls_mpi_size(&operation->ecp.d); + memcpy(key_output, operation->ecp.d.p, *key_len); + + return mbedtls_to_psa_error(status); +#else + (void) operation; + (void) key_output; + (void) key_len; return PSA_ERROR_NOT_SUPPORTED; +#endif } -psa_status_t psa_generate_key_iop_abort( - psa_generate_key_iop_t *operation) +psa_status_t mbedtls_psa_generate_key_abort( + mbedtls_psa_generate_key_iop_operation_t *operation) { +#if defined(MBEDTLS_ECP_C) + mbedtls_ecp_keypair_free(&operation->ecp); + operation->num_ops = 0; + return PSA_SUCCESS; +#else (void) operation; - return PSA_ERROR_NOT_SUPPORTED; +#endif } /****************************************************************/ diff --git a/tf-psa-crypto/include/psa/crypto.h b/tf-psa-crypto/include/psa/crypto.h index aa58033a01a2..80a400d4cc0d 100644 --- a/tf-psa-crypto/include/psa/crypto.h +++ b/tf-psa-crypto/include/psa/crypto.h @@ -5500,7 +5500,7 @@ psa_status_t psa_generate_key_iop_setup( */ psa_status_t psa_generate_key_iop_complete( psa_generate_key_iop_t *operation, - psa_key_id_t *key); + mbedtls_svc_key_id_t *key); /** * \brief Abort a key generation operation. diff --git a/tf-psa-crypto/include/psa/crypto_builtin_composites.h b/tf-psa-crypto/include/psa/crypto_builtin_composites.h index c14f5dd110f5..e1f06dd6b9e1 100644 --- a/tf-psa-crypto/include/psa/crypto_builtin_composites.h +++ b/tf-psa-crypto/include/psa/crypto_builtin_composites.h @@ -211,4 +211,20 @@ typedef struct { #define MBEDTLS_PSA_PAKE_OPERATION_INIT { { 0 } } +typedef struct { +#if defined(MBEDTLS_ECP_C) + mbedtls_ecp_keypair MBEDTLS_PRIVATE(ecp); + uint32_t num_ops; +#else + /* Make the struct non-empty if algs not supported. */ + unsigned MBEDTLS_PRIVATE(dummy); +#endif +} mbedtls_psa_generate_key_iop_operation_t; + +#if defined(MBEDTLS_ECP_C) +#define MBEDTLS_PSA_KEY_AGREEMENT_INTERRUPTIBLE_OPERATION_INIT { { 0 }, 0 } +#else +#define MBEDTLS_PSA_KEY_AGREEMENT_INTERRUPTIBLE_OPERATION_INIT { 0 } +#endif + #endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/tf-psa-crypto/include/psa/crypto_driver_contexts_composites.h b/tf-psa-crypto/include/psa/crypto_driver_contexts_composites.h index 5a484fceccf7..2e6e42fc9acc 100644 --- a/tf-psa-crypto/include/psa/crypto_driver_contexts_composites.h +++ b/tf-psa-crypto/include/psa/crypto_driver_contexts_composites.h @@ -147,5 +147,10 @@ typedef union { #endif } psa_driver_pake_context_t; +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_generate_key_iop_operation_t mbedtls_ctx; +} psa_driver_generate_key_context_t; + #endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */ /* End of automatically generated file. */ diff --git a/tf-psa-crypto/include/psa/crypto_struct.h b/tf-psa-crypto/include/psa/crypto_struct.h index 2eec948119bc..025326528d41 100644 --- a/tf-psa-crypto/include/psa/crypto_struct.h +++ b/tf-psa-crypto/include/psa/crypto_struct.h @@ -542,14 +542,16 @@ struct psa_generate_key_iop_s { * any driver (i.e. none of the driver contexts are active). */ unsigned int MBEDTLS_PRIVATE(id); - + psa_driver_generate_key_context_t MBEDTLS_PRIVATE(ctx); + const psa_key_attributes_t *MBEDTLS_PRIVATE(attributes); + unsigned int MBEDTLS_PRIVATE(error_occurred) : 1; #endif }; #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) && !defined(MBEDTLS_PSA_CRYPTO_C) #define PSA_GENERATE_KEY_IOP_INIT { 0 } #else -#define PSA_GENERATE_KEY_IOP_INIT { 0 } +#define PSA_GENERATE_KEY_IOP_INIT { 0, { 0 }, 0, 0 } #endif static inline struct psa_generate_key_iop_s diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function index cee73b0861cc..d71f195a0a97 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function @@ -10089,6 +10089,7 @@ void generate_key(int type_arg, int is_large_key) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t iop_key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_type_t type = type_arg; psa_key_usage_t usage = usage_arg; size_t bits = bits_arg; @@ -10096,6 +10097,8 @@ void generate_key(int type_arg, psa_status_t expected_status = expected_status_arg; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t iop_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_generate_key_iop_t operation = PSA_GENERATE_KEY_IOP_INIT; PSA_ASSERT(psa_crypto_init()); @@ -10111,28 +10114,48 @@ void generate_key(int type_arg, TEST_ASSUME(status != PSA_ERROR_INSUFFICIENT_MEMORY); } TEST_EQUAL(status, expected_status); + if (expected_status == PSA_SUCCESS) { + /* Test the key information */ + PSA_ASSERT(psa_get_key_attributes(key, &got_attributes)); + TEST_EQUAL(psa_get_key_type(&got_attributes), type); + TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); + + /* Do something with the key according to its type and permitted usage. */ + TEST_EQUAL(mbedtls_test_psa_exercise_key(key, usage, alg, 0), 1); + } + if (!PSA_KEY_TYPE_IS_ECC(type)) { + expected_status = PSA_ERROR_NOT_SUPPORTED; + } + +#if !defined(MBEDTLS_ECP_RESTARTABLE) + expected_status = PSA_ERROR_NOT_SUPPORTED; +#endif + + status = psa_generate_key_iop_setup(&operation, &attributes); + TEST_EQUAL(status, expected_status); if (expected_status != PSA_SUCCESS) { goto exit; } - /* Test the key information */ - PSA_ASSERT(psa_get_key_attributes(key, &got_attributes)); - TEST_EQUAL(psa_get_key_type(&got_attributes), type); - TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); + PSA_ASSERT(psa_generate_key_iop_complete(&operation, &iop_key)); + + PSA_ASSERT(psa_get_key_attributes(iop_key, &iop_attributes)); + TEST_EQUAL(psa_get_key_type(&iop_attributes), type); + TEST_EQUAL(psa_get_key_bits(&iop_attributes), bits); /* Do something with the key according to its type and permitted usage. */ - if (!mbedtls_test_psa_exercise_key(key, usage, alg, 0)) { - goto exit; - } + TEST_EQUAL(mbedtls_test_psa_exercise_key(iop_key, usage, alg, 0), 1); exit: + psa_generate_key_iop_abort(&operation); /* * Key attributes may have been returned by psa_get_key_attributes() * thus reset them as required. */ psa_reset_key_attributes(&got_attributes); - + psa_reset_key_attributes(&iop_attributes); psa_destroy_key(key); + psa_destroy_key(iop_key); PSA_DONE(); } /* END_CASE */