Add {sign/verify}_hash_abort_internal
Ensure that num_ops is cleared when manual abort is called, but obviously not
when an operation just completes, and test this.
Signed-off-by: Paul Elliott <paul.elliott@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index e3be650..f7228bc 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3155,6 +3155,25 @@
return operation->num_ops;
}
+static psa_status_t psa_sign_hash_abort_internal(
+ psa_sign_hash_interruptible_operation_t *operation)
+{
+ if (operation->id == 0) {
+ /* The object has (apparently) been initialized but it is not (yet)
+ * in use. It's ok to call abort on such an object, and there's
+ * nothing to do. */
+ return PSA_SUCCESS;
+ }
+
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ status = psa_driver_wrapper_sign_hash_abort(operation);
+
+ operation->id = 0;
+
+ return status;
+}
+
psa_status_t psa_sign_hash_start(
psa_sign_hash_interruptible_operation_t *operation,
mbedtls_svc_key_id_t key, psa_algorithm_t alg,
@@ -3202,7 +3221,7 @@
exit:
if (status != PSA_SUCCESS) {
- psa_sign_hash_abort(operation);
+ psa_sign_hash_abort_internal(operation);
}
unlock_status = psa_unlock_key_slot(slot);
@@ -3259,7 +3278,7 @@
/* If signature_size is 0 then we have nothing to do. We must not
* call memset because signature may be NULL in this case.*/
- psa_sign_hash_abort(operation);
+ psa_sign_hash_abort_internal(operation);
}
return status;
@@ -3268,6 +3287,20 @@
psa_status_t psa_sign_hash_abort(
psa_sign_hash_interruptible_operation_t *operation)
{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ status = psa_sign_hash_abort_internal(operation);
+
+ /* We clear the number of ops done here, so that it is not cleared when
+ * the operation fails or succeeds, only on manual abort. */
+ operation->num_ops = 0;
+
+ return status;
+}
+
+static psa_status_t psa_verify_hash_abort_internal(
+ psa_verify_hash_interruptible_operation_t *operation)
+{
if (operation->id == 0) {
/* The object has (apparently) been initialized but it is not (yet)
* in use. It's ok to call abort on such an object, and there's
@@ -3275,11 +3308,13 @@
return PSA_SUCCESS;
}
- psa_driver_wrapper_sign_hash_abort(operation);
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ status = psa_driver_wrapper_verify_hash_abort(operation);
operation->id = 0;
- return PSA_SUCCESS;
+ return status;
}
psa_status_t psa_verify_hash_start(
@@ -3324,7 +3359,7 @@
signature, signature_length);
if (status != PSA_SUCCESS) {
- psa_verify_hash_abort(operation);
+ psa_verify_hash_abort_internal(operation);
}
unlock_status = psa_unlock_key_slot(slot);
@@ -3354,7 +3389,7 @@
operation);
if (status != PSA_OPERATION_INCOMPLETE) {
- psa_verify_hash_abort(operation);
+ psa_verify_hash_abort_internal(operation);
}
return status;
@@ -3363,18 +3398,15 @@
psa_status_t psa_verify_hash_abort(
psa_verify_hash_interruptible_operation_t *operation)
{
- if (operation->id == 0) {
- /* The object has (apparently) been initialized but it is not (yet)
- * in use. It's ok to call abort on such an object, and there's
- * nothing to do. */
- return PSA_SUCCESS;
- }
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- psa_driver_wrapper_verify_hash_abort(operation);
+ status = psa_verify_hash_abort_internal(operation);
- operation->id = 0;
+ /* We clear the number of ops done here, so that it is not cleared when
+ * the operation fails or succeeds, only on manual abort. */
+ operation->num_ops = 0;
- return PSA_SUCCESS;
+ return status;
}
/****************************************************************/