Merge pull request #9490 from waleed-elmelegy-arm/add-iop-key-agrmnt-api
Add PSA interruptible key agreement APIs
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b3a84b3..a7f92f5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -410,6 +410,7 @@
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/drivers/builtin/include
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/drivers/everest/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/library
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/core
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tf-psa-crypto/drivers/builtin/src)
diff --git a/ChangeLog.d/add-psa-iop-key-agreement.txt b/ChangeLog.d/add-psa-iop-key-agreement.txt
new file mode 100644
index 0000000..92dfde1
--- /dev/null
+++ b/ChangeLog.d/add-psa-iop-key-agreement.txt
@@ -0,0 +1,4 @@
+Features
+ * Add an interruptible version of key agreement to the PSA interface.
+ See psa_key_agreement_iop_setup() and related functions.
+
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8318e8b..eba6c51 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,5 +1,6 @@
set(libs
${mbedtls_target}
+ ${everest_target}
${CMAKE_THREAD_LIBS_INIT}
)
diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h
index 7ab2bea..4d674e7 100644
--- a/tests/include/test/psa_test_wrappers.h
+++ b/tests/include/test/psa_test_wrappers.h
@@ -475,13 +475,13 @@
psa_status_t mbedtls_test_wrap_psa_key_agreement_iop_complete(
psa_key_agreement_iop_t *arg0_operation,
- psa_key_id_t *arg1_key);
+ mbedtls_svc_key_id_t *arg1_key);
#define psa_key_agreement_iop_complete(arg0_operation, arg1_key) \
mbedtls_test_wrap_psa_key_agreement_iop_complete(arg0_operation, arg1_key)
psa_status_t mbedtls_test_wrap_psa_key_agreement_iop_setup(
psa_key_agreement_iop_t *arg0_operation,
- psa_key_id_t arg1_private_key,
+ mbedtls_svc_key_id_t arg1_private_key,
const uint8_t *arg2_peer_key,
size_t arg3_peer_key_length,
psa_algorithm_t arg4_alg,
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 e5c7225..44d87d6 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 @@
return 1;
}
+size_t psasim_serialise_psa_key_agreement_iop_t_needs(
+ psa_key_agreement_iop_t value)
+{
+ return sizeof(value);
+}
+
+int psasim_serialise_psa_key_agreement_iop_t(uint8_t **pos,
+ size_t *remaining,
+ psa_key_agreement_iop_t value)
+{
+ if (*remaining < sizeof(value)) {
+ return 0;
+ }
+
+ memcpy(*pos, &value, sizeof(value));
+ *pos += sizeof(value);
+
+ return 1;
+}
+
+int psasim_deserialise_psa_key_agreement_iop_t(uint8_t **pos,
+ size_t *remaining,
+ psa_key_agreement_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 523ce80..02f6bcb 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_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_key_agreement_iop_t()
+ * to serialise a `psa_key_agreement_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_key_agreement_iop_t() to serialise
+ * the given value.
+ */
+size_t psasim_serialise_psa_key_agreement_iop_t_needs(
+ psa_key_agreement_iop_t value);
+
+/** Serialise a `psa_key_agreement_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_key_agreement_iop_t(uint8_t **pos,
+ size_t *remaining,
+ psa_key_agreement_iop_t value);
+
+/** Deserialise a `psa_key_agreement_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_key_agreement_iop_t` to receive the value
+ * deserialised from the buffer.
+ *
+ * \return \c 1 on success ("okay"), \c 0 on error.
+ */
+int psasim_deserialise_psa_key_agreement_iop_t(uint8_t **pos,
+ size_t *remaining,
+ psa_key_agreement_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 31c93ae..054841e 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_key_agreement_iop_t);
grep(s/-/ /g, @types);
diff --git a/tests/scripts/test_psa_constant_names.py b/tests/scripts/test_psa_constant_names.py
index 6c402dc..8ed0fee 100755
--- a/tests/scripts/test_psa_constant_names.py
+++ b/tests/scripts/test_psa_constant_names.py
@@ -163,6 +163,7 @@
parser.add_argument('--include', '-I',
action='append', default=['tf-psa-crypto/include',
'tf-psa-crypto/drivers/builtin/include',
+ 'tf-psa-crypto/drivers/everest/include',
'include'],
help='Directory for header files')
parser.add_argument('--keep-c',
diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c
index 6e42a8b..1277df0 100644
--- a/tests/src/psa_test_wrappers.c
+++ b/tests/src/psa_test_wrappers.c
@@ -835,7 +835,7 @@
/* Wrapper for psa_key_agreement_iop_complete */
psa_status_t mbedtls_test_wrap_psa_key_agreement_iop_complete(
psa_key_agreement_iop_t *arg0_operation,
- psa_key_id_t *arg1_key)
+ mbedtls_svc_key_id_t *arg1_key)
{
psa_status_t status = (psa_key_agreement_iop_complete)(arg0_operation, arg1_key);
return status;
@@ -844,7 +844,7 @@
/* Wrapper for psa_key_agreement_iop_setup */
psa_status_t mbedtls_test_wrap_psa_key_agreement_iop_setup(
psa_key_agreement_iop_t *arg0_operation,
- psa_key_id_t arg1_private_key,
+ mbedtls_svc_key_id_t arg1_private_key,
const uint8_t *arg2_peer_key,
size_t arg3_peer_key_length,
psa_algorithm_t arg4_alg,
diff --git a/tf-psa-crypto/core/psa_crypto.c b/tf-psa-crypto/core/psa_crypto.c
index e1e0eab..ceaa243 100644
--- a/tf-psa-crypto/core/psa_crypto.c
+++ b/tf-psa-crypto/core/psa_crypto.c
@@ -7731,6 +7731,24 @@
return (status == PSA_SUCCESS) ? unlock_status : status;
}
+static psa_status_t validate_key_agreement_params(const psa_key_attributes_t *attributes,
+ psa_algorithm_t alg)
+{
+ psa_key_type_t key_type;
+
+ if (!PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ key_type = psa_get_key_type(attributes);
+ if (key_type != PSA_KEY_TYPE_DERIVE && key_type != PSA_KEY_TYPE_RAW_DATA
+ && key_type != PSA_KEY_TYPE_HMAC && key_type != PSA_KEY_TYPE_PASSWORD) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ return PSA_SUCCESS;
+}
+
psa_status_t psa_key_agreement(mbedtls_svc_key_id_t private_key,
const uint8_t *peer_key,
size_t peer_key_length,
@@ -7741,14 +7759,12 @@
psa_status_t status;
uint8_t shared_secret[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
size_t shared_secret_len;
- psa_key_type_t key_type;
*key = MBEDTLS_SVC_KEY_ID_INIT;
- key_type = psa_get_key_type(attributes);
- if (key_type != PSA_KEY_TYPE_DERIVE && key_type != PSA_KEY_TYPE_RAW_DATA
- && key_type != PSA_KEY_TYPE_HMAC && key_type != PSA_KEY_TYPE_PASSWORD) {
- return PSA_ERROR_INVALID_ARGUMENT;
+ status = validate_key_agreement_params(attributes, alg);
+ if (status != PSA_SUCCESS) {
+ return status;
}
status = psa_raw_key_agreement(alg, private_key, peer_key, peer_key_length, shared_secret,
@@ -7763,6 +7779,161 @@
return status;
}
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
+
+static psa_status_t psa_key_agreement_iop_abort_internal(psa_key_agreement_iop_t *operation)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ if (operation->id == 0) {
+ return PSA_SUCCESS;
+ }
+
+ status = mbedtls_psa_key_agreement_iop_abort(&operation->mbedtls_ctx);
+
+ operation->id = 0;
+
+ return status;
+}
+#endif
+
+uint32_t psa_key_agreement_iop_get_num_ops(
+ psa_key_agreement_iop_t *operation)
+{
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
+ return operation->num_ops;
+#else
+ (void) operation;
+ return 0;
+#endif
+}
+
+psa_status_t psa_key_agreement_iop_setup(
+ psa_key_agreement_iop_t *operation,
+ mbedtls_svc_key_id_t private_key,
+ const uint8_t *peer_key,
+ size_t peer_key_length,
+ psa_algorithm_t alg,
+ const psa_key_attributes_t *attributes)
+{
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_key_slot_t *slot = NULL;
+
+ if (operation->id != 0 || operation->error_occurred) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ status = validate_key_agreement_params(attributes, alg);
+ if (status != PSA_SUCCESS) {
+ operation->error_occurred = 1;
+ return status;
+ }
+
+ status = psa_get_and_lock_transparent_key_slot_with_policy(
+ private_key, &slot, PSA_KEY_USAGE_DERIVE, alg);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ operation->attributes = *attributes;
+
+ operation->num_ops = 0;
+
+ /* To be removed later when driver dispatch is added. */
+ operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
+
+ status = mbedtls_psa_key_agreement_iop_setup(&operation->mbedtls_ctx,
+ &slot->attr, slot->key.data,
+ slot->key.bytes, peer_key,
+ peer_key_length);
+
+ operation->num_ops = mbedtls_psa_key_agreement_iop_get_num_ops(&operation->mbedtls_ctx);
+
+exit:
+ unlock_status = psa_unregister_read_under_mutex(slot);
+ if (status != PSA_SUCCESS) {
+ operation->error_occurred = 1;
+ psa_key_agreement_iop_abort_internal(operation);
+ return status;
+ }
+ if (unlock_status != PSA_SUCCESS) {
+ operation->error_occurred = 1;
+ }
+ return unlock_status;
+#else
+ (void) operation;
+ (void) private_key;
+ (void) peer_key;
+ (void) peer_key_length;
+ (void) alg;
+ (void) attributes;
+ return PSA_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+psa_status_t psa_key_agreement_iop_complete(
+ psa_key_agreement_iop_t *operation,
+ mbedtls_svc_key_id_t *key)
+{
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
+
+ if (operation->id == 0 || operation->error_occurred) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ psa_status_t status;
+ uint8_t intermediate_key[PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE];
+ size_t key_len = 0;
+
+ status = mbedtls_psa_key_agreement_iop_complete(&operation->mbedtls_ctx, intermediate_key,
+ sizeof(intermediate_key),
+ &key_len);
+
+ operation->num_ops = mbedtls_psa_key_agreement_iop_get_num_ops(&operation->mbedtls_ctx);
+
+ if (status == PSA_SUCCESS) {
+ status = psa_import_key(&operation->attributes, intermediate_key,
+ key_len, key);
+ }
+
+ if (status != PSA_SUCCESS && status != PSA_OPERATION_INCOMPLETE) {
+ operation->error_occurred = 1;
+ psa_key_agreement_iop_abort_internal(operation);
+ }
+ mbedtls_platform_zeroize(intermediate_key, sizeof(intermediate_key));
+ return status;
+#else
+ (void) operation;
+ (void) key;
+ return PSA_ERROR_BAD_STATE;
+#endif
+}
+
+psa_status_t psa_key_agreement_iop_abort(
+ psa_key_agreement_iop_t *operation)
+{
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
+ psa_status_t status;
+
+ status = psa_key_agreement_iop_abort_internal(operation);
+
+ operation->num_ops = 0;
+ operation->error_occurred = 0;
+
+ return status;
+#else
+ (void) operation;
+ return PSA_SUCCESS;
+#endif
+}
+
/****************************************************************/
/* Random generation */
/****************************************************************/
diff --git a/tf-psa-crypto/core/psa_crypto_core.h b/tf-psa-crypto/core/psa_crypto_core.h
index 1753554..d775761 100644
--- a/tf-psa-crypto/core/psa_crypto_core.h
+++ b/tf-psa-crypto/core/psa_crypto_core.h
@@ -701,6 +701,110 @@
size_t *shared_secret_length);
/**
+ * \brief Get the total number of ops that a key agreement operation has taken
+ * since its start.
+ *
+ * \note The signature of this function is that of a PSA driver
+ * key_agreement_get_num_ops entry point. This function behaves as an
+ * key_agreement_get_num_ops entry point as defined in the PSA driver
+ * interface specification for transparent drivers.
+ *
+ * \param[in] operation The \c mbedtls_psa_key_agreement_interruptible_operation_t to use.
+ * This must be initialized first.
+ *
+ * \return Total number of operations.
+ */
+uint32_t mbedtls_psa_key_agreement_iop_get_num_ops(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation);
+
+/**
+ * \brief Set up a new interruptible key agreement operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ * key_agreement_setup entry point. This function behaves as a
+ * key_agreement_setup entry point as defined in the PSA driver interface
+ * specification for transparent drivers.
+ *
+ * \param[in] operation The \c psa_key_agreement_iop_t to use.
+ * This must be initialized first.
+ * \param[in] private_key_attributes The attributes of the private key to use for the
+ * operation.
+ * \param[in] private_key_buffer The buffer containing the private key
+ * context.
+ * \param[in] private_key_buffer_len Size of the \p private_key_buffer buffer in
+ * bytes.
+ * \param[in] peer_key The buffer containing the key context
+ * of the peer's public key.
+ * \param[in] peer_key_length Size of the \p peer_key buffer in
+ * bytes.
+ * \retval #PSA_SUCCESS
+ * The operation started successfully - call \c psa_key_agreement_complete()
+ * with the same context to complete the operation
+ * \retval #PSA_ERROR_INVALID_ARGUMENT
+ * An unsupported, incorrectly formatted or incorrect type of key was
+ * used.
+ * \retval #PSA_ERROR_NOT_SUPPORTED Either no internal interruptible operations
+ * are currently supported, or the key type is currently unsupported.
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * There was insufficient memory to load the key representation.
+ */
+psa_status_t mbedtls_psa_key_agreement_iop_setup(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation,
+ const psa_key_attributes_t *private_key_attributes,
+ const uint8_t *private_key_buffer,
+ size_t private_key_buffer_len,
+ const uint8_t *peer_key,
+ size_t peer_key_length);
+
+/**
+ * \brief Continue and eventually complete a key agreement operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ * key_agreement_complete entry point. This function behaves as a
+ * key_agreement_complete entry point as defined in the PSA driver
+ * interface specification for transparent drivers.
+ *
+ * \param[in] operation The \c mbedtls_psa_key_agreement_interruptible_operation_t to use.
+ * This must be initialized first.
+ * \param[out] shared_secret The buffer to which the shared secret
+ * is to be written.
+ * \param[in] shared_secret_size Size of the \p shared_secret buffer in
+ * bytes.
+ * \param[out] shared_secret_length On success, the number of bytes that make
+ * up the returned shared secret.
+ * \retval #PSA_SUCCESS
+ * The shared secret was calculated successfully.
+ * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * Internal interruptible operations are currently not supported.
+ * \retval #PSA_ERROR_BUFFER_TOO_SMALL
+ * \p shared_secret_size is too small
+ */
+psa_status_t mbedtls_psa_key_agreement_iop_complete(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation,
+ uint8_t *shared_secret,
+ size_t shared_secret_size,
+ size_t *shared_secret_length);
+
+/**
+ * \brief Abort a key agreement operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ * key_agreement_abort entry point. This function behaves as a
+ * key_agreement_abort entry point as defined in the PSA driver
+ * interface specification for transparent drivers.
+ *
+ * \param[in] operation The \c mbedtls_psa_key_agreement_interruptible_operation_t to abort.
+ * This must be initialized first.
+ *
+ * \retval #PSA_SUCCESS
+ * The operation was aborted successfully.
+ */
+psa_status_t mbedtls_psa_key_agreement_iop_abort(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation);
+
+
+/**
* \brief Set the maximum number of ops allowed to be executed by an
* interruptible function in a single call.
*
diff --git a/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h b/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h
index 22d5d84..40b7277 100644
--- a/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h
+++ b/tf-psa-crypto/drivers/builtin/include/mbedtls/bignum.h
@@ -238,7 +238,7 @@
}
mbedtls_mpi;
-#define MBEDTLS_MPI_INIT { 0, 0, 0 }
+#define MBEDTLS_MPI_INIT { 0, 1, 0 }
/**
* \brief Initialize an MPI context.
diff --git a/tf-psa-crypto/drivers/builtin/include/mbedtls/ecdh.h b/tf-psa-crypto/drivers/builtin/include/mbedtls/ecdh.h
index a6a5069..3d3e479 100644
--- a/tf-psa-crypto/drivers/builtin/include/mbedtls/ecdh.h
+++ b/tf-psa-crypto/drivers/builtin/include/mbedtls/ecdh.h
@@ -95,6 +95,17 @@
} mbedtls_ecdh_context_mbed;
#endif
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+#define MBEDTLS_ECDH_CONTEXT_MBED_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_POINT_INIT, \
+ MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_RESTART_INIT }
+#else
+#define MBEDTLS_ECDH_CONTEXT_MBED_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_POINT_INIT, \
+ MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT }
+#endif
+
/**
*
* \warning Performing multiple operations concurrently on the same
@@ -141,6 +152,35 @@
}
mbedtls_ecdh_context;
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_POINT_INIT, \
+ MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_PF_UNCOMPRESSED, \
+ MBEDTLS_ECP_POINT_INIT, MBEDTLS_ECP_POINT_INIT, \
+ MBEDTLS_MPI_INIT, 0, \
+ MBEDTLS_ECP_RESTART_INIT }
+#else
+#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_GROUP_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_POINT_INIT, \
+ MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
+ MBEDTLS_ECP_PF_UNCOMPRESSED, \
+ MBEDTLS_ECP_POINT_INIT, MBEDTLS_ECP_POINT_INIT, \
+ MBEDTLS_MPI_INIT }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#else
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_PF_UNCOMPRESSED, MBEDTLS_ECP_DP_NONE, \
+ MBEDTLS_ECDH_VARIANT_NONE, \
+ { MBEDTLS_ECDH_CONTEXT_MBED_INIT }, 0 }
+#else
+#define MBEDTLS_ECDH_CONTEXT_INIT { MBEDTLS_ECP_PF_UNCOMPRESSED, MBEDTLS_ECP_DP_NONE, \
+ MBEDTLS_ECDH_VARIANT_NONE, \
+ { MBEDTLS_ECDH_CONTEXT_MBED_INIT } }
+#endif /* MBEDTLS_ECP_RESTARTABLE */
+#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
+
/**
* \brief Return the ECP group for provided context.
*
diff --git a/tf-psa-crypto/drivers/builtin/include/mbedtls/ecp.h b/tf-psa-crypto/drivers/builtin/include/mbedtls/ecp.h
index b340614..87d63ed 100644
--- a/tf-psa-crypto/drivers/builtin/include/mbedtls/ecp.h
+++ b/tf-psa-crypto/drivers/builtin/include/mbedtls/ecp.h
@@ -255,6 +255,7 @@
#define MBEDTLS_ECP_GROUP_INIT { MBEDTLS_ECP_DP_NONE, MBEDTLS_MPI_INIT, MBEDTLS_MPI_INIT, \
MBEDTLS_MPI_INIT, MBEDTLS_ECP_POINT_INIT, MBEDTLS_MPI_INIT, \
0, 0, 0, NULL, NULL, NULL, NULL, NULL, 0 }
+
/**
* \name SECTION: Module settings
*
@@ -372,6 +373,8 @@
mbedtls_ecp_restart_muladd_ctx *MBEDTLS_PRIVATE(ma); /*!< ecp_muladd() sub-context */
} mbedtls_ecp_restart_ctx;
+#define MBEDTLS_ECP_RESTART_INIT { 0, 0, NULL, NULL }
+
/*
* Operation counts for restartable functions
*/
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 acb2482..57b10c9 100644
--- a/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c
+++ b/tf-psa-crypto/drivers/builtin/src/psa_crypto_ecp.c
@@ -630,47 +630,110 @@
/* Interruptible ECC Key Agreement */
/****************************************************************/
-uint32_t psa_key_agreement_iop_get_num_ops(
- psa_key_agreement_iop_t *operation)
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) && defined(MBEDTLS_ECP_RESTARTABLE)
+
+uint32_t mbedtls_psa_key_agreement_iop_get_num_ops(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation)
{
- (void) operation;
- return 0;
+ return operation->num_ops;
}
-psa_status_t psa_key_agreement_iop_setup(
- psa_key_agreement_iop_t *operation,
- psa_key_id_t private_key,
+psa_status_t mbedtls_psa_key_agreement_iop_setup(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation,
+ const psa_key_attributes_t *private_key_attributes,
+ const uint8_t *private_key_buffer,
+ size_t private_key_buffer_len,
const uint8_t *peer_key,
- size_t peer_key_length,
- psa_algorithm_t alg,
- const psa_key_attributes_t *attributes)
+ size_t peer_key_length)
{
- (void) operation;
- (void) private_key;
- (void) peer_key;
- (void) peer_key_length;
- (void) alg;
- (void) attributes;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ mbedtls_ecp_keypair *our_key = NULL;
+ mbedtls_ecp_keypair *their_key = NULL;
+ mbedtls_ecdh_init(&operation->ctx);
+ mbedtls_ecdh_enable_restart(&operation->ctx);
+
+ /* We need to clear number of ops here in case there was a previous
+ complete operation which doesn't reset it after finsishing. */
+ operation->num_ops = 0;
+
+ status = mbedtls_psa_ecp_load_representation(
+ psa_get_key_type(private_key_attributes),
+ psa_get_key_bits(private_key_attributes),
+ private_key_buffer,
+ private_key_buffer_len,
+ &our_key);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = mbedtls_to_psa_error(
+ mbedtls_ecdh_get_params(&operation->ctx, our_key, MBEDTLS_ECDH_OURS));
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ mbedtls_ecp_keypair_free(our_key);
+ mbedtls_free(our_key);
+ our_key = NULL;
+
+ status = mbedtls_psa_ecp_load_representation(
+ PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(private_key_attributes)),
+ psa_get_key_bits(private_key_attributes),
+ peer_key,
+ peer_key_length,
+ &their_key);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ /* mbedtls_psa_ecp_load_representation() calls mbedtls_ecp_check_pubkey() which
+ takes MBEDTLS_ECP_OPS_CHK amount of ops. */
+ operation->num_ops += MBEDTLS_ECP_OPS_CHK;
+
+ status = mbedtls_to_psa_error(
+ mbedtls_ecdh_get_params(&operation->ctx, their_key, MBEDTLS_ECDH_THEIRS));
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+exit:
+ mbedtls_ecp_keypair_free(our_key);
+ mbedtls_free(our_key);
+ mbedtls_ecp_keypair_free(their_key);
+ mbedtls_free(their_key);
+ return status;
+}
+
+psa_status_t mbedtls_psa_key_agreement_iop_complete(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation,
+ uint8_t *shared_secret,
+ size_t shared_secret_size,
+ size_t *shared_secret_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops());
+
+ status = mbedtls_to_psa_error(mbedtls_ecdh_calc_secret(&operation->ctx, shared_secret_length,
+ shared_secret,
+ shared_secret_size,
+ mbedtls_psa_get_random,
+ MBEDTLS_PSA_RANDOM_STATE));
+
+ operation->num_ops += operation->ctx.rs.ops_done;
+
+ return status;
+}
+
+psa_status_t mbedtls_psa_key_agreement_iop_abort(
+ mbedtls_psa_key_agreement_interruptible_operation_t *operation)
+{
+ operation->num_ops = 0;
+ mbedtls_ecdh_free(&operation->ctx);
return PSA_SUCCESS;
}
-psa_status_t psa_key_agreement_iop_complete(
- psa_key_agreement_iop_t *operation,
- psa_key_id_t *key)
-{
- (void) operation;
- (void) key;
-
- return PSA_SUCCESS;
-}
-
-psa_status_t psa_key_agreement_iop_abort(
- psa_key_agreement_iop_t *operation)
-{
- (void) operation;
-
- return PSA_SUCCESS;
-}
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
#endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/tf-psa-crypto/drivers/everest/include/everest/everest.h b/tf-psa-crypto/drivers/everest/include/everest/everest.h
index 392e792..f83413e 100644
--- a/tf-psa-crypto/drivers/everest/include/everest/everest.h
+++ b/tf-psa-crypto/drivers/everest/include/everest/everest.h
@@ -41,6 +41,7 @@
mbedtls_x25519_context ctx;
} mbedtls_ecdh_context_everest;
+#define MBEDTLS_ECDH_CONTEXT_EVEREST_INIT {MBEDTLS_X25519_CONTEXT_INIT}
/**
* \brief This function sets up the ECDH context with the information
diff --git a/tf-psa-crypto/drivers/everest/include/everest/x25519.h b/tf-psa-crypto/drivers/everest/include/everest/x25519.h
index ef314d2..39d01de 100644
--- a/tf-psa-crypto/drivers/everest/include/everest/x25519.h
+++ b/tf-psa-crypto/drivers/everest/include/everest/x25519.h
@@ -47,6 +47,8 @@
unsigned char peer_point[MBEDTLS_X25519_KEY_SIZE_BYTES];
} mbedtls_x25519_context;
+#define MBEDTLS_X25519_CONTEXT_INIT {{0}, {0}}
+
/**
* \brief This function initializes an x25519 context.
*
diff --git a/tf-psa-crypto/drivers/p256-m/CMakeLists.txt b/tf-psa-crypto/drivers/p256-m/CMakeLists.txt
index af046da..ae44123 100644
--- a/tf-psa-crypto/drivers/p256-m/CMakeLists.txt
+++ b/tf-psa-crypto/drivers/p256-m/CMakeLists.txt
@@ -12,6 +12,7 @@
$<BUILD_INTERFACE:${MBEDTLS_DIR}/include>
$<BUILD_INTERFACE:${TF_PSA_CRYPTO_DIR}/include>
$<BUILD_INTERFACE:${TF_PSA_CRYPTO_DIR}/drivers/builtin/include>
+ $<BUILD_INTERFACE:${TF_PSA_CRYPTO_DIR}/drivers/everest/include>
$<INSTALL_INTERFACE:include>
PRIVATE ${MBEDTLS_DIR}/library/
${TF_PSA_CRYPTO_DIR}/core)
diff --git a/tf-psa-crypto/include/psa/crypto.h b/tf-psa-crypto/include/psa/crypto.h
index 58b6887..62f1dca 100644
--- a/tf-psa-crypto/include/psa/crypto.h
+++ b/tf-psa-crypto/include/psa/crypto.h
@@ -5123,7 +5123,7 @@
psa_status_t psa_key_agreement_iop_setup(
psa_key_agreement_iop_t *operation,
- psa_key_id_t private_key,
+ mbedtls_svc_key_id_t private_key,
const uint8_t *peer_key,
size_t peer_key_length,
psa_algorithm_t alg,
@@ -5208,7 +5208,7 @@
*/
psa_status_t psa_key_agreement_iop_complete(
psa_key_agreement_iop_t *operation,
- psa_key_id_t *key);
+ mbedtls_svc_key_id_t *key);
/**
* \brief Abort a key agreement operation.
diff --git a/tf-psa-crypto/include/psa/crypto_builtin_composites.h b/tf-psa-crypto/include/psa/crypto_builtin_composites.h
index c9c0c6b..14e759b 100644
--- a/tf-psa-crypto/include/psa/crypto_builtin_composites.h
+++ b/tf-psa-crypto/include/psa/crypto_builtin_composites.h
@@ -33,6 +33,10 @@
#endif
#include "mbedtls/chachapoly.h"
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
+#include "mbedtls/ecdh.h"
+#endif
+
/*
* MAC multi-part operation definitions.
*/
@@ -227,4 +231,21 @@
#define MBEDTLS_PSA_GENERATE_KEY_IOP_INIT { 0 }
#endif
+/* Context structure for the Mbed TLS interruptible key agreement implementation. */
+typedef struct {
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) && defined(MBEDTLS_ECP_RESTARTABLE)
+ mbedtls_ecdh_context MBEDTLS_PRIVATE(ctx);
+ uint32_t MBEDTLS_PRIVATE(num_ops);
+#else
+ /* Make the struct non-empty if algs not supported. */
+ unsigned MBEDTLS_PRIVATE(dummy);
+#endif
+} mbedtls_psa_key_agreement_interruptible_operation_t;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) && defined(MBEDTLS_ECP_RESTARTABLE)
+#define MBEDTLS_PSA_KEY_AGREEMENT_IOP_INIT { MBEDTLS_ECDH_CONTEXT_INIT, 0 }
+#else
+#define MBEDTLS_PSA_KEY_AGREEMENT_IOP_INIT { 0 }
+#endif
+
#endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */
diff --git a/tf-psa-crypto/include/psa/crypto_struct.h b/tf-psa-crypto/include/psa/crypto_struct.h
index 76ef5c4..ded3af0 100644
--- a/tf-psa-crypto/include/psa/crypto_struct.h
+++ b/tf-psa-crypto/include/psa/crypto_struct.h
@@ -508,14 +508,18 @@
* any driver (i.e. none of the driver contexts are active).
*/
unsigned int MBEDTLS_PRIVATE(id);
-
+ mbedtls_psa_key_agreement_interruptible_operation_t MBEDTLS_PRIVATE(mbedtls_ctx);
+ uint32_t MBEDTLS_PRIVATE(num_ops);
+ 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_KEY_AGREEMENT_IOP_INIT { 0 }
#else
-#define PSA_KEY_AGREEMENT_IOP_INIT { 0 }
+#define PSA_KEY_AGREEMENT_IOP_INIT { 0, MBEDTLS_PSA_KEY_AGREEMENT_IOP_INIT, 0, \
+ PSA_KEY_ATTRIBUTES_INIT, 0 }
#endif
static inline struct psa_key_agreement_iop_s
diff --git a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data
index dab2ee7..707e5b0 100644
--- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data
+++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.data
@@ -7357,6 +7357,102 @@
depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT:PSA_WANT_DH_RFC7919_6144
key_agreement_output:PSA_ALG_KEY_AGREEMENT(PSA_ALG_FFDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):"bbaec0a6c20e67aa77bd9db1f682b20227d3e17944ccf9ea639e437202309c29dc876a8d209e81e59e1d7584284089c4ffb3356e28acca6c94164752e7e331cee7fccdb3d08604a5faaf91c02cab4ea6ad2926e28d1dee9fadd437b2b8a5116c689869c0972529e4c362aaa8427c95f42d8a60c1f38f9f672c837a097bcd1a8c068c11a33ce36517915dae1ba47e2646aef079e6c84b9656991ef0f6ceb9f7f95c97e7232cc5c41c0335aed99169133702cb8d95ef1e9eb5af583f3469a77277243fe61f16dd5b4f9f4972e3d30050f289f891daf8146ff87cf2845c419dfe2ca0525c5e2e8fc6566d7118fadaf0103b24319061f862e2584e5fba1063d55365b78379820d335ee924ac0871ceb3a2a339fba250011371b53426bab5f48e9704b7a9e77d14d5f6cafcfbdb45463e6935be31bc87eafd9b6d228a5b76c2baa6364f450a4ac557dd07ed4b1a13f5603e2b3bb270e831f0f2950f52c52d866fdaeb748a4cbb6f20b332795fffb8cf77a34ef75d8105973f1fdada6a3b050a28c12268104a8f1cce9a86ebce1749a97e9e5f00608229799aa5b7a356fca7b8bb5c7829cb18a136836bb37f5165deb89b33f0b69c473236025bc649d382d008fbc7c8c84390b9d86b173e45fa1e162e0eabd7914f2ec4c26d5350be064fc0d68bf16446188dd4a76ac1267a63b764070b48342a884891eeddbba95257348764c646aef160523af105a719aedb041a28b81516dbe89e80592f687eb341aff447a4165ac145889ae3e8a14c948c82b581b35d8f7d1c4f5e0f838773a472ad0025b1ca0b1c8bfe58c42079194b9aa9c5a1139472e7f917655a3ae297c9a8e3bfa6e108242a5ac01b92a9e94d7b51fbe2732d68f1ec5c12607add5e9bddbe5a4837e9fa16a66b5d83456df4f9febb14158dc5ea467b7cc288fe58f28cade38fa3d4c8864c3cb93bda6d39ad28f7dab8b8c0be34f675d268d82ba6a2e22ba49a5e7de5d08edae35ec17d1419288719a4f82dfb7aad6f7b68c4216c69b83af7438771622e48381841d1fcb6081d41b1b84eae37912b34dc8df1794bb47ad87f94d9c841aa98":"31b48495f611fd0205994fc523bfbc6b72949417f28392d30c1c98878bde0ca467ab6d6fe58522df9749154f95c9683f9590c295cd2b62ff9c59f2a71aaa3f7cb72761740cdcac8994c3623e8c07e2991dac60c2ccba818623013467cfca64f9a3b58523d4a4982571365db08aa9de048303c2a48d1c02c9aafc2ecd6eaae1c5bce8314503d0711d755b59134cbfc773250690121f58fc5171ea34fe88e753d5ab3da23e0557aa326b408c2f55aad2b6f40504509c2203f353bcb17e7b2c61fdcba04c3f8c136ef5d14c38ded6ff0455f59f3052b52b2d45f76a2c3b4b09af388a57ebd9d33393853b83b8033b6973cf662907e62380b66b4ce04b82ab8fcd35f40083a330587e27daa0f84c21fc5d04af03104785f85cb880ae61024cf6cfd1dc14149fdff6653968458fb5761cf2cbf8263e915099eb209d1d149bd7a5b4e48b108f07a1f7c17aa4cbf7b3aa25075956f93f127d46b6392834e7781e46f0e2d1ba14ce2f2d91f9db106bf94c7110ace1bf6105cd9351031e0ec7b52a599ae41256581c1379be5882c352c750709c1b8d37cd8d1442ae5547db0f5a1371eca211f028428572a0fcc4c0852ec1f9be4de14a32536087f520cdeaf54c52b203bb6ff0008b2099fb0e1dff4547563a71db416c5b97ef8e7677d8edd15a2ae75dc64b817117fe5e0478cfa1a18e15cb44cfcc990c5f01127b3906187c18562c876631a046a70015e84b6c553be23168e572cedb5912a6505ff8bb65722cc0e9556e967600711b8d8a8e414811c9809aa3e15f680fdbb2b2297e414824fda530b501b278c35f3f0f0ac61da3262de7b8aa44e31544c593c8521f8ce4921b8d7df7d7382c97718efd03650caa5620bc0e6fb9753dfe26c78b0b6a3231391b9324ee6b7c81b45e7e90e5573ab6cb263b114d78eaba7eb2bc668dd57b6eef126abcdf8355656beac58ddbaeb0551a4083fd5a2bd0e405d35737b7c3c6f0f0190403c13b57e3ef7b6b76206725758523ef98e4053fb8e05147a74577b61b0935dc5eb699945d3290e78bcc9015c9c3210ffed7d6e96c6c8202e46ad37155d07f3e8c2d9a":"10":"5d324ec021d57640dee474c442f3a25390de6ff13175f70fad977003bd78fcdfeda87d2a5cc8447b9729990b11e7949c6ebb37a2d3c2fa69a85d79d216a6a489c8c5186576c112ca94c1bce156b819fb010a4168e8c91e777b87dceb0de4f1828c45297e3b513f4ff57bfb874a7c0d3cd709332922394bcddbc0bf959668810ce1ec8dbff662ea620b9ee7186cdde9845185ea87ded242fbffb7f526d875b6b1dbd09a4008b4d2c1034621a75efd6140c7d6fc883d79f7c3b7f7ae21b74e62a9c26f682c9dd48cacdc7f0c4ec5eb32a5c505aa5949d4008ece502bca5612f84ae73164acd2d3399cc9aee5cf615de62dd31c63a407f5c988b5c61a124ce08c"
+PSA key agreement interruptible: ECDH SECP256R1 (RFC 5903): Num of ops: 5
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de":5
+
+PSA key agreement interruptible: ECDH SECP256R1 (RFC 5903): Num of ops: 100
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de":100
+
+PSA key agreement interruptible: ECDH SECP256R1 (RFC 5903): Num of ops: 0
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de":0
+
+PSA key agreement interruptible: ECDH SECP256R1 (RFC 5903): Num of ops: Max
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA key agreement interruptible: ECDH SECP384R1 (RFC 5903): Num of ops: 5
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f160647b67414dce655e35b538041e649ee3faef896783ab194":"04e558dbef53eecde3d3fccfc1aea08a89a987475d12fd950d83cfa41732bc509d0d1ac43a0336def96fda41d0774a3571dcfbec7aacf3196472169e838430367f66eebe3c6e70c416dd5f0c68759dd1fff83fa40142209dff5eaad96db9e6386c":"11187331c279962d93d604243fd592cb9d0a926f422e47187521287e7156c5c4d603135569b9e9d09cf5d4a270f59746":5
+
+PSA key agreement interruptible: ECDH SECP384R1 (RFC 5903): Num of ops: 100
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f160647b67414dce655e35b538041e649ee3faef896783ab194":"04e558dbef53eecde3d3fccfc1aea08a89a987475d12fd950d83cfa41732bc509d0d1ac43a0336def96fda41d0774a3571dcfbec7aacf3196472169e838430367f66eebe3c6e70c416dd5f0c68759dd1fff83fa40142209dff5eaad96db9e6386c":"11187331c279962d93d604243fd592cb9d0a926f422e47187521287e7156c5c4d603135569b9e9d09cf5d4a270f59746":100
+
+PSA key agreement interruptible: ECDH SECP384R1 (RFC 5903): Num of ops: 0
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f160647b67414dce655e35b538041e649ee3faef896783ab194":"04e558dbef53eecde3d3fccfc1aea08a89a987475d12fd950d83cfa41732bc509d0d1ac43a0336def96fda41d0774a3571dcfbec7aacf3196472169e838430367f66eebe3c6e70c416dd5f0c68759dd1fff83fa40142209dff5eaad96db9e6386c":"11187331c279962d93d604243fd592cb9d0a926f422e47187521287e7156c5c4d603135569b9e9d09cf5d4a270f59746":0
+
+PSA key agreement interruptible: ECDH SECP384R1 (RFC 5903): Num of ops: Max
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"099f3c7034d4a2c699884d73a375a67f7624ef7c6b3c0f160647b67414dce655e35b538041e649ee3faef896783ab194":"04e558dbef53eecde3d3fccfc1aea08a89a987475d12fd950d83cfa41732bc509d0d1ac43a0336def96fda41d0774a3571dcfbec7aacf3196472169e838430367f66eebe3c6e70c416dd5f0c68759dd1fff83fa40142209dff5eaad96db9e6386c":"11187331c279962d93d604243fd592cb9d0a926f422e47187521287e7156c5c4d603135569b9e9d09cf5d4a270f59746":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA key agreement interruptible: ECDH SECP521R1 (RFC 5903): Num of ops: 5
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_521
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5393dce47608172a095aa85a30fe1c2952c6771d937ba9777f5957b2639bab072462f68c27a57382d4a52":"0400d0b3975ac4b799f5bea16d5e13e9af971d5e9b984c9f39728b5e5739735a219b97c356436adc6e95bb0352f6be64a6c2912d4ef2d0433ced2b6171640012d9460f015c68226383956e3bd066e797b623c27ce0eac2f551a10c2c724d9852077b87220b6536c5c408a1d2aebb8e86d678ae49cb57091f4732296579ab44fcd17f0fc56a":"01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f97894e5e6b2d79b04d1427e73ca4baa240a34786859810c06b3c715a3a8cc3151f2bee417996d19f3ddea":5
+
+PSA key agreement interruptible: ECDH SECP521R1 (RFC 5903): Num of ops: 100
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_521
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5393dce47608172a095aa85a30fe1c2952c6771d937ba9777f5957b2639bab072462f68c27a57382d4a52":"0400d0b3975ac4b799f5bea16d5e13e9af971d5e9b984c9f39728b5e5739735a219b97c356436adc6e95bb0352f6be64a6c2912d4ef2d0433ced2b6171640012d9460f015c68226383956e3bd066e797b623c27ce0eac2f551a10c2c724d9852077b87220b6536c5c408a1d2aebb8e86d678ae49cb57091f4732296579ab44fcd17f0fc56a":"01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f97894e5e6b2d79b04d1427e73ca4baa240a34786859810c06b3c715a3a8cc3151f2bee417996d19f3ddea":100
+
+PSA key agreement interruptible: ECDH SECP521R1 (RFC 5903): Num of ops: 0
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_521
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5393dce47608172a095aa85a30fe1c2952c6771d937ba9777f5957b2639bab072462f68c27a57382d4a52":"0400d0b3975ac4b799f5bea16d5e13e9af971d5e9b984c9f39728b5e5739735a219b97c356436adc6e95bb0352f6be64a6c2912d4ef2d0433ced2b6171640012d9460f015c68226383956e3bd066e797b623c27ce0eac2f551a10c2c724d9852077b87220b6536c5c408a1d2aebb8e86d678ae49cb57091f4732296579ab44fcd17f0fc56a":"01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f97894e5e6b2d79b04d1427e73ca4baa240a34786859810c06b3c715a3a8cc3151f2bee417996d19f3ddea":0
+
+PSA key agreement interruptible: ECDH SECP521R1 (RFC 5903): Num of ops: Max
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_SECP_R1_521
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"0037ade9319a89f4dabdb3ef411aaccca5123c61acab57b5393dce47608172a095aa85a30fe1c2952c6771d937ba9777f5957b2639bab072462f68c27a57382d4a52":"0400d0b3975ac4b799f5bea16d5e13e9af971d5e9b984c9f39728b5e5739735a219b97c356436adc6e95bb0352f6be64a6c2912d4ef2d0433ced2b6171640012d9460f015c68226383956e3bd066e797b623c27ce0eac2f551a10c2c724d9852077b87220b6536c5c408a1d2aebb8e86d678ae49cb57091f4732296579ab44fcd17f0fc56a":"01144c7d79ae6956bc8edb8e7c787c4521cb086fa64407f97894e5e6b2d79b04d1427e73ca4baa240a34786859810c06b3c715a3a8cc3151f2bee417996d19f3ddea":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA key agreement interruptible: ECDH brainpoolP256r1 (RFC 7027): Num of ops: 5
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"81db1ee100150ff2ea338d708271be38300cb54241d79950f77b063039804f1d":"048d2d688c6cf93e1160ad04cc4429117dc2c41825e1e9fca0addd34e6f1b39f7b990c57520812be512641e47034832106bc7d3e8dd0e4c7f1136d7006547cec6a":"89afc39d41d3b327814b80940b042590f96556ec91e6ae7939bce31f3a18bf2b":5
+
+PSA key agreement interruptible: ECDH brainpoolP256r1 (RFC 7027): Num of ops: 100
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"81db1ee100150ff2ea338d708271be38300cb54241d79950f77b063039804f1d":"048d2d688c6cf93e1160ad04cc4429117dc2c41825e1e9fca0addd34e6f1b39f7b990c57520812be512641e47034832106bc7d3e8dd0e4c7f1136d7006547cec6a":"89afc39d41d3b327814b80940b042590f96556ec91e6ae7939bce31f3a18bf2b":100
+
+PSA key agreement interruptible: ECDH brainpoolP256r1 (RFC 7027): Num of ops: 0
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"81db1ee100150ff2ea338d708271be38300cb54241d79950f77b063039804f1d":"048d2d688c6cf93e1160ad04cc4429117dc2c41825e1e9fca0addd34e6f1b39f7b990c57520812be512641e47034832106bc7d3e8dd0e4c7f1136d7006547cec6a":"89afc39d41d3b327814b80940b042590f96556ec91e6ae7939bce31f3a18bf2b":0
+
+PSA key agreement interruptible: ECDH brainpoolP256r1 (RFC 7027): Num of ops: Max
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_256
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"81db1ee100150ff2ea338d708271be38300cb54241d79950f77b063039804f1d":"048d2d688c6cf93e1160ad04cc4429117dc2c41825e1e9fca0addd34e6f1b39f7b990c57520812be512641e47034832106bc7d3e8dd0e4c7f1136d7006547cec6a":"89afc39d41d3b327814b80940b042590f96556ec91e6ae7939bce31f3a18bf2b":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA key agreement interruptible: ECDH brainpoolP384r1 (RFC 7027): Num of ops: 5
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042":"044d44326f269a597a5b58bba565da5556ed7fd9a8a9eb76c25f46db69d19dc8ce6ad18e404b15738b2086df37e71d1eb462d692136de56cbe93bf5fa3188ef58bc8a3a0ec6c1e151a21038a42e9185329b5b275903d192f8d4e1f32fe9cc78c48":"0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42":5
+
+PSA key agreement interruptible: ECDH brainpoolP384r1 (RFC 7027): Num of ops: 100
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042":"044d44326f269a597a5b58bba565da5556ed7fd9a8a9eb76c25f46db69d19dc8ce6ad18e404b15738b2086df37e71d1eb462d692136de56cbe93bf5fa3188ef58bc8a3a0ec6c1e151a21038a42e9185329b5b275903d192f8d4e1f32fe9cc78c48":"0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42":100
+
+PSA key agreement interruptible: ECDH brainpoolP384r1 (RFC 7027): Num of ops: 0
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042":"044d44326f269a597a5b58bba565da5556ed7fd9a8a9eb76c25f46db69d19dc8ce6ad18e404b15738b2086df37e71d1eb462d692136de56cbe93bf5fa3188ef58bc8a3a0ec6c1e151a21038a42e9185329b5b275903d192f8d4e1f32fe9cc78c48":"0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42":0
+
+PSA key agreement interruptible: ECDH brainpoolP384r1 (RFC 7027): Num of ops: Max
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_384
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"1e20f5e048a5886f1f157c74e91bde2b98c8b52d58e5003d57053fc4b0bd65d6f15eb5d1ee1610df870795143627d042":"044d44326f269a597a5b58bba565da5556ed7fd9a8a9eb76c25f46db69d19dc8ce6ad18e404b15738b2086df37e71d1eb462d692136de56cbe93bf5fa3188ef58bc8a3a0ec6c1e151a21038a42e9185329b5b275903d192f8d4e1f32fe9cc78c48":"0bd9d3a7ea0b3d519d09d8e48d0785fb744a6b355e6304bc51c229fbbce239bbadf6403715c35d4fb2a5444f575d4f42":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
+PSA key agreement interruptible: ECDH brainpoolP512r1 (RFC 7027): Num of ops: 5
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_512
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a56850a38bd87bd59b09e80279609ff333eb9d4c061231fb26f92eeb04982a5f1d1764cad57665422":"049d45f66de5d67e2e6db6e93a59ce0bb48106097ff78a081de781cdb31fce8ccbaaea8dd4320c4119f1e9cd437a2eab3731fa9668ab268d871deda55a5473199f2fdc313095bcdd5fb3a91636f07a959c8e86b5636a1e930e8396049cb481961d365cc11453a06c719835475b12cb52fc3c383bce35e27ef194512b71876285fa":"a7927098655f1f9976fa50a9d566865dc530331846381c87256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d24f11a9b5c0bef679fe1454b21c4cd1f":5
+
+PSA key agreement interruptible: ECDH brainpoolP512r1 (RFC 7027): Num of ops: 100
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_512
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a56850a38bd87bd59b09e80279609ff333eb9d4c061231fb26f92eeb04982a5f1d1764cad57665422":"049d45f66de5d67e2e6db6e93a59ce0bb48106097ff78a081de781cdb31fce8ccbaaea8dd4320c4119f1e9cd437a2eab3731fa9668ab268d871deda55a5473199f2fdc313095bcdd5fb3a91636f07a959c8e86b5636a1e930e8396049cb481961d365cc11453a06c719835475b12cb52fc3c383bce35e27ef194512b71876285fa":"a7927098655f1f9976fa50a9d566865dc530331846381c87256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d24f11a9b5c0bef679fe1454b21c4cd1f":100
+
+PSA key agreement interruptible: ECDH brainpoolP512r1 (RFC 7027): Num of ops: 0
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_512
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a56850a38bd87bd59b09e80279609ff333eb9d4c061231fb26f92eeb04982a5f1d1764cad57665422":"049d45f66de5d67e2e6db6e93a59ce0bb48106097ff78a081de781cdb31fce8ccbaaea8dd4320c4119f1e9cd437a2eab3731fa9668ab268d871deda55a5473199f2fdc313095bcdd5fb3a91636f07a959c8e86b5636a1e930e8396049cb481961d365cc11453a06c719835475b12cb52fc3c383bce35e27ef194512b71876285fa":"a7927098655f1f9976fa50a9d566865dc530331846381c87256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d24f11a9b5c0bef679fe1454b21c4cd1f":0
+
+PSA key agreement interruptible: ECDH brainpoolP512r1 (RFC 7027): Num of ops: Max
+depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE:PSA_WANT_ECC_BRAINPOOL_P_R1_512
+key_agreement_interruptible:PSA_ALG_ECDH:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):"16302ff0dbbb5a8d733dab7141c1b45acbc8715939677f6a56850a38bd87bd59b09e80279609ff333eb9d4c061231fb26f92eeb04982a5f1d1764cad57665422":"049d45f66de5d67e2e6db6e93a59ce0bb48106097ff78a081de781cdb31fce8ccbaaea8dd4320c4119f1e9cd437a2eab3731fa9668ab268d871deda55a5473199f2fdc313095bcdd5fb3a91636f07a959c8e86b5636a1e930e8396049cb481961d365cc11453a06c719835475b12cb52fc3c383bce35e27ef194512b71876285fa":"a7927098655f1f9976fa50a9d566865dc530331846381c87256baf3226244b76d36403c024d7bbf0aa0803eaff405d3d24f11a9b5c0bef679fe1454b21c4cd1f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED
+
PSA generate random: 0 bytes
generate_random:0
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 eaafd90..99e8880 100644
--- a/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function
+++ b/tf-psa-crypto/tests/suites/test_suite_psa_crypto.function
@@ -1234,6 +1234,37 @@
*max_completes = 1;
}
}
+
+/* ECP need to block for a minimum number of operations even if max_ops is set to a
+ lower value. This functions calculates this minimum value given the curve size
+ and the window size. */
+static uint32_t interruptible_key_agreement_get_min_num_ops(size_t key_bits)
+{
+ /* Those values are taken from documentation of mbedtls_ecp_set_max_ops()
+ in ecp.h. Those values can change at any time. */
+ switch (key_bits) {
+ case 256:
+ {
+ const uint32_t min_values[5] = { 208, 208, 160, 136, 124 }; // P-256
+ return min_values[6 - MBEDTLS_ECP_WINDOW_SIZE];
+ break;
+ }
+ case 384:
+ {
+ const uint32_t min_values[5] = { 682, 416, 320, 272, 248 }; // P-384
+ return min_values[6 - MBEDTLS_ECP_WINDOW_SIZE];
+ break;
+ }
+ case 512:
+ case 521:
+ {
+ const uint32_t min_values[5] = { 1364, 832, 640, 544, 496 }; // P-521
+ return min_values[6 - MBEDTLS_ECP_WINDOW_SIZE];
+ break;
+ }
+ }
+ return 0;
+}
#endif /* MBEDTLS_ECP_RESTARTABLE */
#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) && defined(MBEDTLS_ASN1_PARSE_C)
@@ -9826,6 +9857,116 @@
}
/* END_CASE */
+/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
+void key_agreement_interruptible(int alg_arg,
+ int our_key_type_arg, data_t *our_key_data,
+ data_t *peer_key_data,
+ data_t *expected_output, int max_ops_arg)
+{
+ mbedtls_svc_key_id_t our_key = MBEDTLS_SVC_KEY_ID_INIT;
+ mbedtls_svc_key_id_t output_key = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_algorithm_t alg = alg_arg;
+ psa_key_type_t our_key_type = our_key_type_arg;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_attributes_t shared_secret_attributes = PSA_KEY_ATTRIBUTES_INIT;
+ unsigned char *output = NULL;
+ size_t output_length = ~0;
+ size_t key_bits;
+ uint32_t max_ops = max_ops_arg;
+ uint32_t num_ops = 0;
+ uint32_t min_num_ops = 0;
+ size_t num_ops_prior = 0;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+
+ psa_key_agreement_iop_t operation = psa_key_agreement_iop_init();
+
+ PSA_ASSERT(psa_crypto_init());
+
+ psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
+ psa_set_key_algorithm(&attributes, alg);
+ psa_set_key_type(&attributes, our_key_type);
+ PSA_ASSERT(psa_import_key(&attributes,
+ our_key_data->x, our_key_data->len,
+ &our_key));
+
+ PSA_ASSERT(psa_get_key_attributes(our_key, &attributes));
+ key_bits = psa_get_key_bits(&attributes);
+
+ psa_set_key_type(&shared_secret_attributes, PSA_KEY_TYPE_DERIVE);
+ psa_set_key_usage_flags(&shared_secret_attributes, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
+
+ /* Validate size macros */
+ TEST_LE_U(expected_output->len,
+ PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(our_key_type, key_bits));
+ TEST_LE_U(PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(our_key_type, key_bits),
+ PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE);
+
+ psa_interruptible_set_max_ops(max_ops);
+
+ TEST_CALLOC(output, expected_output->len);
+
+ num_ops_prior = psa_key_agreement_iop_get_num_ops(&operation);
+ TEST_EQUAL(num_ops_prior, 0);
+
+ PSA_ASSERT(psa_key_agreement_iop_setup(&operation, our_key, peer_key_data->x,
+ peer_key_data->len, alg, &shared_secret_attributes));
+
+ num_ops_prior = psa_key_agreement_iop_get_num_ops(&operation);
+ /* psa_key_agreement_iop_setup() takes a number of ops because it calls
+ mbedtls_ecp_check_pubkey() */
+ TEST_EQUAL(num_ops_prior, MBEDTLS_ECP_OPS_CHK);
+
+ min_num_ops = interruptible_key_agreement_get_min_num_ops(key_bits);
+
+ do {
+
+ status = psa_key_agreement_iop_complete(&operation, &output_key);
+
+ if (status == PSA_SUCCESS || status == PSA_OPERATION_INCOMPLETE) {
+ /* Ensure that each operation finished in less than or equal
+ maximum number of operations specefied unless the maximum
+ number of operations was less than the minium possible for
+ the curve size. */
+ num_ops = psa_key_agreement_iop_get_num_ops(&operation);
+ if (max_ops <= min_num_ops) {
+ TEST_LE_U(num_ops - num_ops_prior, min_num_ops);
+ } else {
+ TEST_LE_U(num_ops - num_ops_prior, max_ops);
+ }
+
+ num_ops_prior = num_ops;
+
+ /* Ensure calling get_num_ops() twice still returns the same
+ * number of ops as previously reported. */
+ num_ops = psa_key_agreement_iop_get_num_ops(&operation);
+
+ TEST_EQUAL(num_ops, num_ops_prior);
+ }
+ } while (status == PSA_OPERATION_INCOMPLETE);
+
+ TEST_EQUAL(status, PSA_SUCCESS);
+
+ PSA_ASSERT(psa_export_key(output_key, output, expected_output->len, &output_length));
+
+ TEST_MEMORY_COMPARE(output, output_length,
+ expected_output->x, expected_output->len);
+
+ PSA_ASSERT(psa_key_agreement_iop_abort(&operation));
+
+ num_ops = psa_key_agreement_iop_get_num_ops(&operation);
+ TEST_EQUAL(num_ops, 0);
+
+exit:
+ psa_destroy_key(our_key);
+ psa_destroy_key(output_key);
+ mbedtls_free(output);
+ PSA_DONE();
+}
+
+/* END_CASE */
+
+
/* BEGIN_CASE */
void key_agreement_capacity(int alg_arg,
int our_key_type_arg, data_t *our_key_data,