diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function index 9b7b0ee14..c2f353496 100644 --- a/tests/suites/test_suite_gcm.function +++ b/tests/suites/test_suite_gcm.function @@ -1,5 +1,57 @@ /* BEGIN_HEADER */ #include "mbedtls/gcm.h" + +/* Use the multipart interface to process the encrypted data in two parts + * and check that the output matches the expected output. + * The context must have been set up with the key. */ +static int check_multipart( mbedtls_gcm_context *ctx, + int mode, + const data_t *iv, + const data_t *add, + const data_t *input, + const data_t *expected_output, + const data_t *tag, + size_t n1 ) +{ + int ok = 0; + uint8_t *output = NULL; + size_t n2 = input->len - n1; + + /* Sanity checks on the test data */ + TEST_ASSERT( n1 <= input->len ); + TEST_EQUAL( input->len, expected_output->len ); + + TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode, + iv->x, iv->len, + add->x, add->len ) ); + + /* Allocate a tight buffer for each update call. This way, if the function + * tries to write beyond the advertised required buffer size, this will + * count as an overflow for memory sanitizers and static checkers. */ + ASSERT_ALLOC( output, n1 ); + TEST_EQUAL( 0, mbedtls_gcm_update( ctx, n1, input->x, output ) ); + ASSERT_COMPARE( output, n1, expected_output->x, n1 ); + mbedtls_free( output ); + output = NULL; + + ASSERT_ALLOC( output, n2 ); + TEST_EQUAL( 0, mbedtls_gcm_update( ctx, n2, input->x + n1, output ) ); + ASSERT_COMPARE( output, n2, expected_output->x + n1, n2 ); + mbedtls_free( output ); + output = NULL; + + ASSERT_ALLOC( output, tag->len ); + TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, output, tag->len ) ); + ASSERT_COMPARE( output, tag->len, tag->x, tag->len ); + mbedtls_free( output ); + output = NULL; + + ok = 1; +exit: + mbedtls_free( output ); + return( ok ); +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -43,6 +95,7 @@ void gcm_encrypt_and_tag( int cipher_id, data_t * key_str, unsigned char tag_output[16]; mbedtls_gcm_context ctx; size_t tag_len = tag_len_bits / 8; + size_t n1; mbedtls_gcm_init( &ctx ); @@ -55,10 +108,18 @@ void gcm_encrypt_and_tag( int cipher_id, data_t * key_str, { 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, src_str->x, output, tag_len, tag_output ) == 0 ); - TEST_ASSERT( mbedtls_test_hexcmp( output, dst->x, - src_str->len, dst->len ) == 0 ); - TEST_ASSERT( mbedtls_test_hexcmp( tag_output, tag->x, - tag_len, tag->len ) == 0 ); + ASSERT_COMPARE( output, src_str->len, dst->x, dst->len ); + ASSERT_COMPARE( tag_output, tag_len, tag->x, tag->len ); + + for( n1 = 16; n1 < src_str->len; n1 += 16 ) + { + mbedtls_test_set_step( n1 ); + if( !check_multipart( &ctx, MBEDTLS_GCM_ENCRYPT, + iv_str, add_str, src_str, + dst, tag, + n1 ) ) + goto exit; + } } exit: @@ -77,6 +138,7 @@ void gcm_decrypt_and_verify( int cipher_id, data_t * key_str, mbedtls_gcm_context ctx; int ret; size_t tag_len = tag_len_bits / 8; + size_t n1; mbedtls_gcm_init( &ctx ); @@ -95,10 +157,17 @@ void gcm_decrypt_and_verify( int cipher_id, data_t * key_str, else { TEST_ASSERT( ret == 0 ); + ASSERT_COMPARE( output, src_str->len, pt_result->x, pt_result->len ); - TEST_ASSERT( mbedtls_test_hexcmp( output, pt_result->x, - src_str->len, - pt_result->len ) == 0 ); + for( n1 = 16; n1 < src_str->len; n1 += 16 ) + { + mbedtls_test_set_step( n1 ); + if( !check_multipart( &ctx, MBEDTLS_GCM_DECRYPT, + iv_str, add_str, src_str, + pt_result, tag_str, + n1 ) ) + goto exit; + } } }