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