Add test cases for AES GCM input and output buffer overlap

This commit adds test cases for input and output buffer overlap. The
data for the test cases is a duplicate of existing encrypt/decrypt test
cases.

The two test functions gcm_<encrypt/decrypt>_input_output_buffer_overlap
are modified to use a single malloc buffer rounded to the nearest
128-bits/16-bytes for input and output.

Signed-off-by: Harry Ramsey <harry.ramsey@arm.com>
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index b0c7bbc..7085e62 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -289,3 +289,103 @@
     TEST_ASSERT(mbedtls_gcm_self_test(1) == 0);
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_encrypt_input_output_buffer_overlap(int cipher_id, data_t *key_str,
+                                             data_t *src_str, data_t *iv_str,
+                                             data_t *add_str, data_t *dst,
+                                             int tag_len_bits, data_t *tag,
+                                             int init_result)
+{
+    unsigned char *buffer = NULL;
+    size_t buffer_len;
+    unsigned char tag_output[16];
+    mbedtls_gcm_context ctx;
+    size_t tag_len = tag_len_bits / 8;
+
+    mbedtls_gcm_init(&ctx);
+
+    /* GCM includes padding and therefore input length can be shorter than the output length
+     * Therefore we must ensure we round up to the nearest 128-bits/16-bytes.
+     */
+    buffer_len = src_str->len;
+    if (buffer_len % 16 != 0 || buffer_len == 0) {
+        buffer_len += (16 - (buffer_len % 16));
+    }
+    TEST_CALLOC(buffer, buffer_len);
+    memcpy(buffer, src_str->x, src_str->len);
+    
+    memset(tag_output, 0x00, 16);
+
+    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
+    if (init_result == 0) {
+        TEST_ASSERT(mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x,
+                                              iv_str->len, add_str->x, add_str->len, buffer,
+                                              buffer, tag_len, tag_output) == 0);
+
+        TEST_ASSERT(mbedtls_test_hexcmp(buffer, dst->x,
+                                        src_str->len, dst->len) == 0);
+        TEST_ASSERT(mbedtls_test_hexcmp(tag_output, tag->x,
+                                        tag_len, tag->len) == 0);
+    }
+
+exit:
+    mbedtls_free(buffer);
+    mbedtls_gcm_free(&ctx);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void gcm_decrypt_input_output_buffer_overlap(int cipher_id, data_t *key_str,
+                                             data_t *src_str, data_t *iv_str,
+                                             data_t *add_str, int tag_len_bits,
+                                             data_t *tag_str, char *result,
+                                             data_t *pt_result, int init_result)
+{
+    unsigned char *buffer = NULL;
+    size_t buffer_len;
+    mbedtls_gcm_context ctx;
+    int ret;
+    size_t tag_len = tag_len_bits / 8;
+
+    mbedtls_gcm_init(&ctx);
+
+    /* GCM includes padding and therefore input length can be shorter than the output length
+     * Therefore we must ensure we round up to the nearest 128-bits/16-bytes.
+     */
+    buffer_len = src_str->len;
+    if (buffer_len % 16 != 0 || buffer_len == 0) {
+        buffer_len += (16 - (buffer_len % 16));
+    }
+    TEST_CALLOC(buffer, buffer_len);
+    memcpy(buffer, src_str->x, src_str->len);
+
+    TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher_id, key_str->x, key_str->len * 8) == init_result);
+    if (init_result == 0) {
+        ret = mbedtls_gcm_auth_decrypt(&ctx,
+                                       src_str->len,
+                                       iv_str->x,
+                                       iv_str->len,
+                                       add_str->x,
+                                       add_str->len,
+                                       tag_str->x,
+                                       tag_len,
+                                       buffer,
+                                       buffer);
+
+        if (strcmp("FAIL", result) == 0) {
+            TEST_ASSERT(ret == MBEDTLS_ERR_GCM_AUTH_FAILED);
+        } else {
+            TEST_ASSERT(ret == 0);
+
+            TEST_ASSERT(mbedtls_test_hexcmp(buffer, pt_result->x,
+                                            src_str->len,
+                                            pt_result->len) == 0);
+        }
+    }
+
+exit:
+    mbedtls_free(buffer);
+    mbedtls_gcm_free(&ctx);
+}
+/* END_CASE */