Merge pull request #126 from ARMmbed/multi-op-abort-on-error

Multipart operations don't always call abort on error - FIX
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index c7d5a67..316acbe 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1110,6 +1110,7 @@
                               size_t hash_size,
                               size_t *hash_length )
 {
+    psa_status_t status;
     int ret;
     size_t actual_hash_length = PSA_HASH_SIZE( operation->alg );
 
@@ -1123,7 +1124,10 @@
         memset( hash, '!', hash_size );
 
     if( hash_size < actual_hash_length )
-        return( PSA_ERROR_BUFFER_TOO_SMALL );
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
 
     switch( operation->alg )
     {
@@ -1168,8 +1172,10 @@
             ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
             break;
     }
+    status = mbedtls_to_psa_error( ret );
 
-    if( ret == 0 )
+exit:
+    if( status == PSA_SUCCESS )
     {
         *hash_length = actual_hash_length;
         return( psa_hash_abort( operation ) );
@@ -1177,7 +1183,7 @@
     else
     {
         psa_hash_abort( operation );
-        return( mbedtls_to_psa_error( ret ) );
+        return( status );
     }
 }
 
@@ -2472,53 +2478,59 @@
                                      size_t iv_size,
                                      size_t *iv_length )
 {
-    int ret = PSA_SUCCESS;
+    psa_status_t status;
+    int ret;
     if( operation->iv_set || ! operation->iv_required )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
     if( iv_size < operation->iv_size )
     {
-        ret = PSA_ERROR_BUFFER_TOO_SMALL;
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
         goto exit;
     }
     ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
                                    iv, operation->iv_size );
     if( ret != 0 )
     {
-        ret = mbedtls_to_psa_error( ret );
+        status = mbedtls_to_psa_error( ret );
         goto exit;
     }
 
     *iv_length = operation->iv_size;
-    ret = psa_cipher_set_iv( operation, iv, *iv_length );
+    status = psa_cipher_set_iv( operation, iv, *iv_length );
 
 exit:
-    if( ret != PSA_SUCCESS )
+    if( status != PSA_SUCCESS )
         psa_cipher_abort( operation );
-    return( ret );
+    return( status );
 }
 
 psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
                                 const unsigned char *iv,
                                 size_t iv_length )
 {
-    int ret = PSA_SUCCESS;
+    psa_status_t status;
+    int ret;
     if( operation->iv_set || ! operation->iv_required )
-        return( PSA_ERROR_BAD_STATE );
+    {
+        status = PSA_ERROR_BAD_STATE;
+        goto exit;
+    }
     if( iv_length != operation->iv_size )
     {
-        psa_cipher_abort( operation );
-        return( PSA_ERROR_INVALID_ARGUMENT );
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto exit;
     }
-    ret =  mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
-    if( ret != 0 )
-    {
+    ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
+    status = mbedtls_to_psa_error( ret );
+exit:
+    if( status == PSA_SUCCESS )
+        operation->iv_set = 1;
+    else
         psa_cipher_abort( operation );
-        return( mbedtls_to_psa_error( ret ) );
-    }
-
-    operation->iv_set = 1;
-
-    return( PSA_SUCCESS );
+    return( status );
 }
 
 psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
@@ -2528,7 +2540,8 @@
                                 size_t output_size,
                                 size_t *output_length )
 {
-    int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+    psa_status_t status;
+    int ret;
     size_t expected_output_size;
     if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
     {
@@ -2544,18 +2557,20 @@
     {
         expected_output_size = input_length;
     }
+
     if( output_size < expected_output_size )
-        return( PSA_ERROR_BUFFER_TOO_SMALL );
+    {
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
+    }
 
     ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
                                  input_length, output, output_length );
-    if( ret != 0 )
-    {
+    status = mbedtls_to_psa_error( ret );
+exit:
+    if( status != PSA_SUCCESS )
         psa_cipher_abort( operation );
-        return( mbedtls_to_psa_error( ret ) );
-    }
-
-    return( PSA_SUCCESS );
+    return( status );
 }
 
 psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,