From 55c0d096b7747b89394be4063d2d35275aa0ced7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 12:37:58 +0200 Subject: [PATCH] chacha20: fix bug in starts() and add test for it Previously the streaming API would fail when encrypting multiple messages with the same key. --- library/chacha20.c | 6 ++++ tests/suites/test_suite_chacha20.function | 37 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/library/chacha20.c b/library/chacha20.c index 5ede4553c..d89000da2 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -243,6 +243,12 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, ctx->initial_state[14] = BYTES_TO_U32_LE( nonce, 4 ); ctx->initial_state[15] = BYTES_TO_U32_LE( nonce, 8 ); + mbedtls_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); + mbedtls_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); + + /* Initially, there's no keystream bytes available */ + ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; + return( 0 ); } diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index 9c0b98522..fb3ad3e79 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -23,6 +23,7 @@ void chacha20_crypt( char *hex_key_string, size_t nonce_len; size_t src_len; size_t dst_len; + mbedtls_chacha20_context ctx; memset( key_str, 0x00, sizeof( key_str ) ); memset( nonce_str, 0x00, sizeof( nonce_str ) ); @@ -39,11 +40,45 @@ void chacha20_crypt( char *hex_key_string, TEST_ASSERT( key_len == 32U ); TEST_ASSERT( nonce_len == 12U ); + /* + * Test the integrated API + */ TEST_ASSERT( mbedtls_chacha20_crypt( key_str, nonce_str, counter, src_len, src_str, output ) == 0 ); hexify( dst_str, output, src_len ); + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 ); - TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0); + /* + * Test the streaming API + */ + mbedtls_chacha20_init( &ctx ); + + TEST_ASSERT( mbedtls_chacha20_setkey( &ctx, key_str ) == 0 ); + + TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 ); + + memset( output, 0x00, sizeof( output ) ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_len, src_str, output ) == 0 ); + + hexify( dst_str, output, src_len ); + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 ); + + /* + * Test the streaming API again, piecewise + */ + + /* Don't reset the context of key, in order to test that starts() do the + * right thing. */ + TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 ); + + memset( output, 0x00, sizeof( output ) ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, 1, src_str, output ) == 0 ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_len - 1, src_str + 1, output + 1 ) == 0 ); + + hexify( dst_str, output, src_len ); + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 ); + + mbedtls_chacha20_free( &ctx ); } /* END_CASE */