diff --git a/ChangeLog.d/add-psa-iop-generate-key.txt b/ChangeLog.d/add-psa-iop-generate-key.txt new file mode 100644 index 000000000000..0f586ee197f8 --- /dev/null +++ b/ChangeLog.d/add-psa-iop-generate-key.txt @@ -0,0 +1,3 @@ +Features + * Add an interruptible version of generate key to the PSA interface. + See psa_generate_key_iop_setup() and related functions. diff --git a/tf-psa-crypto/core/psa_crypto.c b/tf-psa-crypto/core/psa_crypto.c index e18647f22a8e..bb2928331d08 100644 --- a/tf-psa-crypto/core/psa_crypto.c +++ b/tf-psa-crypto/core/psa_crypto.c @@ -8121,8 +8121,7 @@ static psa_status_t psa_generate_key_iop_abort_internal( uint32_t psa_generate_key_iop_get_num_ops( psa_generate_key_iop_t *operation) { - (void) operation; - return 0; + return operation->num_ops; } psa_status_t psa_generate_key_iop_setup( @@ -8197,6 +8196,8 @@ psa_status_t psa_generate_key_iop_complete( goto exit; } + operation->num_ops = mbedtls_psa_generate_key_iop_get_num_ops(&operation->ctx); + status = psa_import_key(&operation->attributes, key_data + (sizeof(key_data) - key_len), key_len, diff --git a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c index b43923e90e30..7fccc72fdc12 100644 --- a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c +++ b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c @@ -596,6 +596,12 @@ psa_status_t mbedtls_psa_key_agreement_ecdh( #if defined(MBEDTLS_ECP_RESTARTABLE) +uint32_t mbedtls_psa_generate_key_iop_get_num_ops( + mbedtls_psa_generate_key_iop_t *operation) +{ + return operation->num_ops; +} + psa_status_t mbedtls_psa_ecp_generate_key_iop_setup( mbedtls_psa_generate_key_iop_t *operation, const psa_key_attributes_t *attributes) @@ -639,6 +645,10 @@ psa_status_t mbedtls_psa_ecp_generate_key_iop_complete( return mbedtls_to_psa_error(status); } + /* Our implementation of key generation only generates the private key + which doesn't invlolve any ECC arithmetic operations so number of ops + is less than 1 but we round up to 1 to differentiate between num ops of + 0 which means no work has been done this facilitates testing. */ operation->num_ops = 1; status = mbedtls_mpi_write_binary(&operation->ecp.d, key_output, key_output_size); diff --git a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h index f3ff32328bb6..8f51fc95311a 100644 --- a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h +++ b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.h @@ -143,6 +143,17 @@ psa_status_t mbedtls_psa_ecp_generate_key( const psa_key_attributes_t *attributes, uint8_t *key_buffer, 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. + * + * \param[in] operation The \c mbedtls_psa_generate_key_iop_t to use. + * This must be initialized first. + * \return Total number of operations. + */ +uint32_t mbedtls_psa_generate_key_iop_get_num_ops( + mbedtls_psa_generate_key_iop_t *operation); + /** * \brief Setup a new interruptible key generation operation. * 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 900c9346d179..4d00142e1f0f 100644 --- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function +++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function @@ -10099,6 +10099,9 @@ void generate_key(int type_arg, 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; + size_t num_ops_prior = 0; + size_t num_ops = 0; + PSA_ASSERT(psa_crypto_init()); @@ -10162,8 +10165,26 @@ void generate_key(int type_arg, goto exit; } + num_ops_prior = psa_generate_key_iop_get_num_ops(&operation); + TEST_EQUAL(num_ops_prior, 0); + do { status = psa_generate_key_iop_complete(&operation, &iop_key); + + if (status == PSA_SUCCESS || status == PSA_OPERATION_INCOMPLETE) { + num_ops = psa_generate_key_iop_get_num_ops(&operation); + + /* Our implementation of key generation only generates the private key + which doesn't invlolve any ECC arithmetic operations so number of ops + is less than 1 but we round up to 1 to differentiate between num ops of + 0 which means no work has been done this facilitates testing. + It is acceptable however for other implementations to set the number of + ops to zero. */ + TEST_LE_U(num_ops_prior + 1, num_ops); + + num_ops_prior = num_ops; + } + } while (status == PSA_OPERATION_INCOMPLETE); TEST_EQUAL(status, PSA_SUCCESS); @@ -10178,6 +10199,10 @@ void generate_key(int type_arg, status = psa_generate_key_iop_complete(&operation, &iop_key); TEST_EQUAL(status, PSA_ERROR_BAD_STATE); + TEST_EQUAL(psa_generate_key_iop_abort(&operation), PSA_SUCCESS); + num_ops = psa_generate_key_iop_get_num_ops(&operation); + TEST_EQUAL(num_ops, 0); + exit: psa_generate_key_iop_abort(&operation); /*