Use macros to manage buffer copies

Signed-off-by: David Horstmann <david.horstmann@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 9e6c2ef..070484c 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -110,6 +110,45 @@
     if (global_data.initialized == 0)  \
     return PSA_ERROR_BAD_STATE;
 
+/* Substitute an input buffer for a local copy of itself.
+ * Assumptions:
+ * - psa_status_t status exists
+ * - An exit label is declared
+ * - The name <buffer>_copy is not used for the given value of <buffer>
+ */
+#define SWAP_FOR_LOCAL_INPUT(input, length) \
+    psa_crypto_local_input_t input ## _copy = PSA_CRYPTO_LOCAL_INPUT_INIT; \
+    status = psa_crypto_local_input_alloc(input, length, &input ## _copy); \
+    if (status != PSA_SUCCESS) { \
+        goto exit; \
+    } \
+    input = input ## _copy.buffer;
+
+#define FREE_LOCAL_INPUT(input) \
+    psa_crypto_local_input_free(&input ## _copy);
+
+/* Substitute an output buffer for a local copy of itself.
+ * Assumptions:
+ * - psa_status_t status exists
+ * - An exit label is declared
+ * - The name <buffer>_copy is not used for the given value of <buffer>
+ */
+#define SWAP_FOR_LOCAL_OUTPUT(output, length) \
+    psa_crypto_local_output_t output ## _copy = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \
+    status = psa_crypto_local_output_alloc(output, length, &output ## _copy); \
+    if (status != PSA_SUCCESS) { \
+        goto exit; \
+    } \
+    output = output ## _copy.buffer;
+
+#define FREE_LOCAL_OUTPUT(output) \
+    psa_status_t local_output_free_status; \
+    local_output_free_status = psa_crypto_local_output_free(&output ## _copy); \
+    if (local_output_free_status != PSA_SUCCESS) { \
+        status = local_output_free_status; \
+    }
+
+
 int psa_can_do_hash(psa_algorithm_t hash_alg)
 {
     (void) hash_alg;
@@ -4342,19 +4381,8 @@
     size_t default_iv_length = 0;
     psa_key_attributes_t attributes;
 
-    psa_crypto_local_input_t local_input = PSA_CRYPTO_LOCAL_INPUT_INIT;
-    status = psa_crypto_local_input_alloc(input, input_length, &local_input);
-    if (status != PSA_SUCCESS) {
-        goto exit;
-    }
-    input = local_input.buffer;
-
-    psa_crypto_local_output_t local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT;
-    status = psa_crypto_local_output_alloc(output, output_size, &local_output);
-    if (status != PSA_SUCCESS) {
-        goto exit;
-    }
-    output = local_output.buffer;
+    SWAP_FOR_LOCAL_INPUT(input, input_length);
+    SWAP_FOR_LOCAL_OUTPUT(output, output_size);
 
     if (!PSA_ALG_IS_CIPHER(alg)) {
         status = PSA_ERROR_INVALID_ARGUMENT;
@@ -4411,8 +4439,8 @@
         *output_length = 0;
     }
 
-    psa_crypto_local_input_free(&local_input);
-    psa_crypto_local_output_free(&local_output);
+    FREE_LOCAL_INPUT(input);
+    FREE_LOCAL_OUTPUT(output);
 
     return status;
 }