Merge pull request #4720 from gilles-peskine-arm/gcm-finish-outlen
Add output_length parameter to mbedtls_gcm_finish
diff --git a/include/mbedtls/gcm.h b/include/mbedtls/gcm.h
index f3c3035..06b06b4 100644
--- a/include/mbedtls/gcm.h
+++ b/include/mbedtls/gcm.h
@@ -339,6 +339,10 @@
* then mbedtls_gcm_finish() never produces any output,
* so \p output_size can be \c 0.
* - \p output_size never needs to be more than \c 15.
+ * \param output_length On success, \p *output_length contains the actual
+ * length of the output written in \p output.
+ * On failure, the content of \p *output_length is
+ * unspecified.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_GCM_BAD_INPUT on failure:
@@ -347,6 +351,7 @@
*/
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *output, size_t output_size,
+ size_t *output_length,
unsigned char *tag, size_t tag_len );
/**
diff --git a/library/cipher.c b/library/cipher.c
index 4f56b52..546cace 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -1109,9 +1109,14 @@
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
+ {
+ size_t output_length;
+ /* The code here doesn't yet support alternative implementations
+ * that can delay up to a block of output. */
return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
- NULL, 0,
+ NULL, 0, &output_length,
tag, tag_len ) );
+ }
#endif
#if defined(MBEDTLS_CHACHAPOLY_C)
@@ -1158,12 +1163,16 @@
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
+ size_t output_length;
+ /* The code here doesn't yet support alternative implementations
+ * that can delay up to a block of output. */
+
if( tag_len > sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
if( 0 != ( ret = mbedtls_gcm_finish(
(mbedtls_gcm_context *) ctx->cipher_ctx,
- NULL, 0,
+ NULL, 0, &output_length,
check_tag, tag_len ) ) )
{
return( ret );
diff --git a/library/gcm.c b/library/gcm.c
index 8fa4ee7..835b1b2 100644
--- a/library/gcm.c
+++ b/library/gcm.c
@@ -532,6 +532,7 @@
int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
unsigned char *output, size_t output_size,
+ size_t *output_length,
unsigned char *tag, size_t tag_len )
{
unsigned char work_buf[16];
@@ -546,6 +547,7 @@
* for the sake of alternative implementations. */
(void) output;
(void) output_size;
+ *output_length = 0;
orig_len = ctx->len * 8;
orig_add_len = ctx->add_len * 8;
@@ -616,7 +618,7 @@
output, length, &olen ) ) != 0 )
return( ret );
- if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, tag, tag_len ) ) != 0 )
+ if( ( ret = mbedtls_gcm_finish( ctx, NULL, 0, &olen, tag, tag_len ) ) != 0 )
return( ret );
return( 0 );
@@ -1068,7 +1070,7 @@
goto exit;
}
- ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
+ ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
if( ret != 0 )
goto exit;
@@ -1140,7 +1142,7 @@
goto exit;
}
- ret = mbedtls_gcm_finish( &ctx, NULL, 0, tag_buf, 16 );
+ ret = mbedtls_gcm_finish( &ctx, NULL, 0, &olen, tag_buf, 16 );
if( ret != 0 )
goto exit;
diff --git a/tests/suites/test_suite_gcm.function b/tests/suites/test_suite_gcm.function
index 49859dd..c530e6b 100644
--- a/tests/suites/test_suite_gcm.function
+++ b/tests/suites/test_suite_gcm.function
@@ -50,7 +50,8 @@
output = NULL;
ASSERT_ALLOC( output, tag->len );
- TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output, tag->len ) );
+ TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
+ TEST_EQUAL( 0, olen );
ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
mbedtls_free( output );
output = NULL;
@@ -96,7 +97,8 @@
output = NULL;
ASSERT_ALLOC( output, tag->len );
- TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output, tag->len ) );
+ TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
+ TEST_EQUAL( 0, olen );
ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
exit:
@@ -125,7 +127,9 @@
}
ASSERT_ALLOC( output_tag, tag->len );
- TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output_tag, tag->len ) );
+ TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen,
+ output_tag, tag->len ) );
+ TEST_EQUAL( 0, olen );
ASSERT_COMPARE( output_tag, tag->len, tag->x, tag->len );
exit:
@@ -138,11 +142,13 @@
const data_t *tag )
{
uint8_t *output = NULL;
+ size_t olen = 0;
TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
iv->x, iv->len ) );
ASSERT_ALLOC( output, tag->len );
- TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, output, tag->len ) );
+ TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
+ TEST_EQUAL( 0, olen );
ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
exit: