Add support for chunked plaintext/cyphertext input.
Signed-off-by: Mateusz Starzyk <mateusz.starzyk@mobica.com>
This commit is contained in:
parent
2ad7d8e1ff
commit
6a15bcf61b
1 changed files with 52 additions and 44 deletions
|
@ -333,59 +333,67 @@ int mbedtls_ccm_update( mbedtls_ccm_context *ctx,
|
|||
{
|
||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||
unsigned char i;
|
||||
size_t len_left, olen;
|
||||
const unsigned char *src;
|
||||
unsigned char *dst;
|
||||
size_t use_len, offset, olen;
|
||||
|
||||
if( output_size < input_len )
|
||||
return( MBEDTLS_ERR_CCM_BAD_INPUT );
|
||||
CCM_VALIDATE_RET( output_length != NULL );
|
||||
*output_len = input_len;
|
||||
|
||||
/*
|
||||
* Authenticate and {en,de}crypt the message.
|
||||
*
|
||||
* The only difference between encryption and decryption is
|
||||
* the respective order of authentication and {en,de}cryption.
|
||||
*/
|
||||
len_left = input_len;
|
||||
src = input;
|
||||
dst = output;
|
||||
|
||||
while( len_left > 0 )
|
||||
if( ctx->processed == 0 )
|
||||
{
|
||||
size_t use_len = len_left > 16 ? 16 : len_left;
|
||||
|
||||
if( ctx->mode == CCM_ENCRYPT )
|
||||
{
|
||||
memset( ctx->b, 0, 16 );
|
||||
memcpy( ctx->b, src, use_len );
|
||||
UPDATE_CBC_MAC;
|
||||
}
|
||||
|
||||
mbedtls_ccm_crypt( ctx, 0, use_len, src, dst );
|
||||
|
||||
if( ctx->mode == CCM_DECRYPT )
|
||||
{
|
||||
memset( ctx->b, 0, 16 );
|
||||
memcpy( ctx->b, dst, use_len );
|
||||
UPDATE_CBC_MAC;
|
||||
}
|
||||
|
||||
dst += use_len;
|
||||
src += use_len;
|
||||
len_left -= use_len;
|
||||
|
||||
/*
|
||||
* Increment counter.
|
||||
* No need to check for overflow thanks to the length check above.
|
||||
*/
|
||||
for( i = 0; i < ctx->q; i++ )
|
||||
if( ++(ctx->ctr)[15-i] != 0 )
|
||||
break;
|
||||
memset( ctx->b, 0, 16 );
|
||||
}
|
||||
|
||||
return (0);
|
||||
while ( input_len > 0 )
|
||||
{
|
||||
offset = ctx->processed % 16;
|
||||
|
||||
use_len = 16 - offset;
|
||||
|
||||
if( use_len > input_len )
|
||||
use_len = input_len;
|
||||
|
||||
ctx->processed += use_len;
|
||||
memcpy( ctx->b + offset, input, use_len );
|
||||
|
||||
if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
|
||||
{
|
||||
if( ctx->mode == CCM_ENCRYPT )
|
||||
{
|
||||
UPDATE_CBC_MAC;
|
||||
ret = mbedtls_ccm_crypt( ctx, 0, use_len, ctx->b, output );
|
||||
if( ret != 0 )
|
||||
return ret;
|
||||
memset( ctx->b, 0, 16 );
|
||||
}
|
||||
|
||||
if( ctx->mode == CCM_DECRYPT )
|
||||
{
|
||||
ret = mbedtls_ccm_crypt( ctx, 0, use_len, ctx->b, output );
|
||||
if( ret != 0 )
|
||||
return ret;
|
||||
memset( ctx->b, 0, 16 );
|
||||
memcpy( ctx->b, output, use_len );
|
||||
UPDATE_CBC_MAC;
|
||||
memset( ctx->b, 0, 16 );
|
||||
}
|
||||
|
||||
input_len -= use_len;
|
||||
input += use_len;
|
||||
output += use_len;
|
||||
|
||||
/*
|
||||
* Increment counter.
|
||||
* No need to check for overflow thanks to the length check above.
|
||||
*/
|
||||
for( i = 0; i < ctx->q; i++ )
|
||||
if( ++(ctx->ctr)[15-i] != 0 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mbedtls_ccm_finish( mbedtls_ccm_context *ctx,
|
||||
|
|
Loading…
Reference in a new issue