Merge pull request #4342 from gilles-peskine-arm/gcm-update-any-length

GCM: allow arbitrary lengths for update
Only the ABI-API-checking job failed and this is expected thus good to go.
This commit is contained in:
Ronald Cron
2021-05-20 15:08:55 +02:00
committed by GitHub
8 changed files with 422 additions and 129 deletions

View File

@@ -1,5 +1,62 @@
/* 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;
size_t olen;
/* 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 ) );
TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, 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 );
olen = 0xdeadbeef;
TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, n1, output, n1, &olen ) );
TEST_EQUAL( n1, olen );
ASSERT_COMPARE( output, olen, expected_output->x, n1 );
mbedtls_free( output );
output = NULL;
ASSERT_ALLOC( output, n2 );
olen = 0xdeadbeef;
TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x + n1, n2, output, n2, &olen ) );
TEST_EQUAL( n2, olen );
ASSERT_COMPARE( output, olen, expected_output->x + n1, n2 );
mbedtls_free( output );
output = NULL;
ASSERT_ALLOC( output, tag->len );
TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, 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 +100,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 +113,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 = 0; n1 <= src_str->len; n1 += 1 )
{
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 +143,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 +162,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 = 0; n1 <= src_str->len; n1 += 1 )
{
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;
}
}
}
@@ -116,6 +190,7 @@ void gcm_invalid_param( )
int valid_mode = MBEDTLS_GCM_ENCRYPT;
int valid_len = sizeof(valid_buffer);
int valid_bitlen = 128, invalid_bitlen = 1;
size_t olen;
mbedtls_gcm_init( &ctx );
@@ -225,42 +300,44 @@ void gcm_invalid_param( )
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_starts( NULL, valid_mode,
valid_buffer, valid_len,
valid_buffer, valid_len ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_starts( &ctx, valid_mode,
NULL, valid_len,
valid_buffer, valid_len ) );
NULL, valid_len ) );
/* mbedtls_gcm_update_ad() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_starts( &ctx, valid_mode,
valid_buffer, valid_len,
mbedtls_gcm_update_ad( &ctx,
NULL, valid_len ) );
/* mbedtls_gcm_update() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_update( NULL, valid_len,
valid_buffer, valid_buffer ) );
mbedtls_gcm_update( NULL, valid_buffer, valid_len,
valid_buffer, valid_len, &olen ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_update( &ctx, valid_len,
NULL, valid_buffer ) );
mbedtls_gcm_update( &ctx, NULL, valid_len,
valid_buffer, valid_len, &olen ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_update( &ctx, valid_len,
valid_buffer, NULL ) );
mbedtls_gcm_update( &ctx, valid_buffer, valid_len,
NULL, valid_len, &olen ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_update( &ctx, valid_buffer, valid_len,
valid_buffer, valid_len, NULL ) );
/* mbedtls_gcm_finish() */
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_finish( NULL, valid_buffer, valid_len ) );
mbedtls_gcm_finish( NULL, NULL, 0, valid_buffer, valid_len ) );
TEST_INVALID_PARAM_RET(
MBEDTLS_ERR_GCM_BAD_INPUT,
mbedtls_gcm_finish( &ctx, NULL, valid_len ) );
mbedtls_gcm_finish( &ctx, NULL, 0, NULL, valid_len ) );
exit:
mbedtls_gcm_free( &ctx );