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;
 }
 
 /****************************************************************/