Split mbedtls_gcm_update_ad out of mbedtls_gcm_starts
The GCM interface now has separate functions to start the operation and to pass the associated data. This is in preparation for allowing the associated data to be passed in chunks with repeatated calls to mbedtls_gcm_update_ad(). Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
a56c448636
commit
295fc13ef3
@ -6,7 +6,9 @@ API changes
|
||||
The software implementation always produces the full output at each
|
||||
call to mbedtls_gcm_update(), but alternative implementations activated
|
||||
by MBEDTLS_GCM_ALT may delay partial blocks to the next call to
|
||||
mbedtls_gcm_update() or mbedtls_gcm_finish().
|
||||
mbedtls_gcm_update() or mbedtls_gcm_finish(). Furthermore, applications
|
||||
no longer pass the associated data to mbedtls_gcm_starts(), but to the
|
||||
new function mbedtls_gcm_update_ad().
|
||||
These changes are backward compatible for users of the cipher API.
|
||||
|
||||
Features
|
||||
|
@ -231,6 +231,26 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
|
||||
* \param iv The initialization vector. This must be a readable buffer of
|
||||
* at least \p iv_len Bytes.
|
||||
* \param iv_len The length of the IV.
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len );
|
||||
|
||||
/**
|
||||
* \brief This function starts a GCM encryption or decryption
|
||||
* operation.
|
||||
*
|
||||
* \note This function may only be called once per operation:
|
||||
* you must pass the whole associated data in a single
|
||||
* call. This limitation will be lifted in a future version
|
||||
* of Mbed TLS.
|
||||
*
|
||||
* \param ctx The GCM context. This must have been started with
|
||||
* mbedtls_gcm_starts() and must not have yet received
|
||||
* any input with mbedtls_gcm_update().
|
||||
* \param add The buffer holding the additional data, or \c NULL
|
||||
* if \p add_len is \c 0.
|
||||
* \param add_len The length of the additional data. If \c 0,
|
||||
@ -238,12 +258,9 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
|
||||
*
|
||||
* \return \c 0 on success.
|
||||
*/
|
||||
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len );
|
||||
int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
|
||||
const unsigned char *add,
|
||||
size_t add_len );
|
||||
|
||||
/**
|
||||
* \brief This function feeds an input buffer into an ongoing GCM
|
||||
|
@ -415,6 +415,15 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
{
|
||||
return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx,
|
||||
ctx->operation,
|
||||
iv, iv_len ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( actual_iv_size != 0 )
|
||||
{
|
||||
memcpy( ctx->iv, iv, actual_iv_size );
|
||||
@ -466,8 +475,8 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
|
||||
{
|
||||
return( mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation,
|
||||
ctx->iv, ctx->iv_size, ad, ad_len ) );
|
||||
return( mbedtls_gcm_update_ad( (mbedtls_gcm_context *) ctx->cipher_ctx,
|
||||
ad, ad_len ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -269,11 +269,8 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
|
||||
}
|
||||
|
||||
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||
int mode,
|
||||
const unsigned char *iv,
|
||||
size_t iv_len,
|
||||
const unsigned char *add,
|
||||
size_t add_len )
|
||||
int mode,
|
||||
const unsigned char *iv, size_t iv_len )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char work_buf[16];
|
||||
@ -283,16 +280,11 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||
|
||||
GCM_VALIDATE_RET( ctx != NULL );
|
||||
GCM_VALIDATE_RET( iv != NULL );
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
|
||||
/* IV and AD are limited to 2^64 bits, so 2^61 bytes */
|
||||
/* IV is are limited to 2^64 bits, so 2^61 bytes */
|
||||
/* IV is not allowed to be zero length */
|
||||
if( iv_len == 0 ||
|
||||
( (uint64_t) iv_len ) >> 61 != 0 ||
|
||||
( (uint64_t) add_len ) >> 61 != 0 )
|
||||
{
|
||||
if( iv_len == 0 || (uint64_t) iv_len >> 61 != 0 )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
}
|
||||
|
||||
memset( ctx->y, 0x00, sizeof(ctx->y) );
|
||||
memset( ctx->buf, 0x00, sizeof(ctx->buf) );
|
||||
@ -337,6 +329,26 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
int mbedtls_gcm_update_ad( mbedtls_gcm_context *ctx,
|
||||
const unsigned char *add, size_t add_len )
|
||||
{
|
||||
const unsigned char *p;
|
||||
size_t use_len, i;
|
||||
|
||||
GCM_VALIDATE_RET( add_len == 0 || add != NULL );
|
||||
|
||||
/* IV is are limited to 2^64 bits, so 2^61 bytes */
|
||||
if( (uint64_t) add_len >> 61 != 0 )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
|
||||
/* Calling update_ad multiple times is not yet supported */
|
||||
if( ctx->add_len != 0 )
|
||||
return( MBEDTLS_ERR_GCM_BAD_INPUT );
|
||||
|
||||
ctx->add_len = add_len;
|
||||
p = add;
|
||||
while( add_len > 0 )
|
||||
@ -546,7 +558,10 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
|
||||
GCM_VALIDATE_RET( length == 0 || output != NULL );
|
||||
GCM_VALIDATE_RET( tag != NULL );
|
||||
|
||||
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 )
|
||||
if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_gcm_update_ad( ctx, add, add_len ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
if( ( ret = mbedtls_gcm_update( ctx, input, length,
|
||||
@ -961,10 +976,14 @@ int mbedtls_gcm_self_test( int verbose )
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
|
||||
iv_test_data[iv_index_test_data[i]],
|
||||
iv_len_test_data[i],
|
||||
additional_test_data[add_index_test_data[i]],
|
||||
add_len_test_data[i] );
|
||||
iv_test_data[iv_index_test_data[i]],
|
||||
iv_len_test_data[i] );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_gcm_update_ad( &ctx,
|
||||
additional_test_data[add_index_test_data[i]],
|
||||
add_len_test_data[i] );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
|
||||
@ -1031,8 +1050,11 @@ int mbedtls_gcm_self_test( int verbose )
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
|
||||
iv_test_data[iv_index_test_data[i]],
|
||||
iv_len_test_data[i],
|
||||
iv_test_data[iv_index_test_data[i]],
|
||||
iv_len_test_data[i] );
|
||||
if( ret != 0 )
|
||||
goto exit;
|
||||
ret = mbedtls_gcm_update_ad( &ctx,
|
||||
additional_test_data[add_index_test_data[i]],
|
||||
add_len_test_data[i] );
|
||||
if( ret != 0 )
|
||||
|
@ -23,8 +23,8 @@ static int check_multipart( mbedtls_gcm_context *ctx,
|
||||
TEST_EQUAL( input->len, expected_output->len );
|
||||
|
||||
TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
|
||||
iv->x, iv->len,
|
||||
add->x, add->len ) );
|
||||
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
|
||||
@ -300,19 +300,17 @@ 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() */
|
||||
|
Loading…
Reference in New Issue
Block a user