From 0f6b66dba10749db919b5f8460d6f4d59caa9cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 7 May 2014 14:43:46 +0200 Subject: [PATCH] CCM operations allow input == output --- include/polarssl/ccm.h | 4 ---- library/ccm.c | 2 +- tests/suites/test_suite_ccm.function | 25 +++++++++++++------------ 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/include/polarssl/ccm.h b/include/polarssl/ccm.h index 50e0b1cc0..439152f9f 100644 --- a/include/polarssl/ccm.h +++ b/include/polarssl/ccm.h @@ -67,8 +67,6 @@ void ccm_free( ccm_context *ctx ); /** * \brief CCM buffer encryption * - * \todo Document if input/output buffers can be the same - * * \param ctx CCM context * \param length length of the input data in bytes * \param iv nonce (initialization vector) @@ -100,8 +98,6 @@ int ccm_encrypt_and_tag( ccm_context *ctx, size_t length, /** * \brief CCM buffer authenticated decryption * - * \todo Document if input/output buffers can be the same - * * \param ctx CCM context * \param length length of the input data * \param iv initialization vector diff --git a/library/ccm.c b/library/ccm.c index 98987b2fb..f245d680e 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -103,7 +103,7 @@ void ccm_free( ccm_context *ctx ) /* * Encrypt or decrypt a partial block with CTR * Warning: using b for temporary storage! src and dst must not be b! - * (This avoids allocating one more 16 bytes buffer.) + * This avoids allocating one more 16 bytes buffer while allowing src == dst. */ #define CTR_CRYPT( dst, src, len ) \ if( ( ret = cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 9a7f42d89..8521fba5d 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -78,7 +78,6 @@ void ccm_encrypt_and_tag( int cipher_id, unsigned char msg[50]; unsigned char iv[13]; unsigned char add[32]; - unsigned char output[50]; unsigned char result[50]; ccm_context ctx; size_t key_len, msg_len, iv_len, add_len, tag_len, result_len; @@ -87,7 +86,6 @@ void ccm_encrypt_and_tag( int cipher_id, memset( msg, 0x00, sizeof( msg ) ); memset( iv, 0x00, sizeof( iv ) ); memset( add, 0x00, sizeof( add ) ); - memset( output, 0x00, sizeof( output ) ); memset( result, 0x00, sizeof( result ) ); key_len = unhexify( key, key_hex ); @@ -99,13 +97,14 @@ void ccm_encrypt_and_tag( int cipher_id, TEST_ASSERT( ccm_init( &ctx, cipher_id, key, key_len * 8 ) == 0 ); + /* Test with input == output */ TEST_ASSERT( ccm_encrypt_and_tag( &ctx, msg_len, iv, iv_len, add, add_len, - msg, output, output + msg_len, tag_len ) == 0 ); + msg, msg, msg + msg_len, tag_len ) == 0 ); - TEST_ASSERT( memcmp( output, result, result_len ) == 0 ); + TEST_ASSERT( memcmp( msg, result, result_len ) == 0 ); /* Check we didn't write past the end */ - TEST_ASSERT( output[result_len] == 0 && output[result_len + 1] == 0 ); + TEST_ASSERT( msg[result_len] == 0 && msg[result_len + 1] == 0 ); ccm_free( &ctx ); } @@ -121,7 +120,7 @@ void ccm_auth_decrypt( int cipher_id, unsigned char msg[50]; unsigned char iv[13]; unsigned char add[32]; - unsigned char output[50]; + unsigned char tag[16]; unsigned char result[50]; ccm_context ctx; size_t key_len, msg_len, iv_len, add_len, result_len; @@ -131,7 +130,7 @@ void ccm_auth_decrypt( int cipher_id, memset( msg, 0x00, sizeof( msg ) ); memset( iv, 0x00, sizeof( iv ) ); memset( add, 0x00, sizeof( add ) ); - memset( output, 0xFF, sizeof( output ) ); + memset( tag, 0x00, sizeof( tag ) ); memset( result, 0x00, sizeof( result ) ); key_len = unhexify( key, key_hex ); @@ -139,6 +138,7 @@ void ccm_auth_decrypt( int cipher_id, iv_len = unhexify( iv, iv_hex ); add_len = unhexify( add, add_hex ); msg_len -= tag_len; + memcpy( tag, msg + msg_len, tag_len ); if( strcmp( "FAIL", result_hex ) == 0 ) { @@ -152,23 +152,24 @@ void ccm_auth_decrypt( int cipher_id, TEST_ASSERT( ccm_init( &ctx, cipher_id, key, key_len * 8 ) == 0 ); + /* Test with input == output */ TEST_ASSERT( ccm_auth_decrypt( &ctx, msg_len, iv, iv_len, add, add_len, - msg, output, msg + msg_len, tag_len ) == ret ); + msg, msg, msg + msg_len, tag_len ) == ret ); if( ret == 0 ) { - TEST_ASSERT( memcmp( output, result, result_len ) == 0 ); + TEST_ASSERT( memcmp( msg, result, result_len ) == 0 ); } else { size_t i; for( i = 0; i < msg_len; i++ ) - TEST_ASSERT( output[i] == 0 ); + TEST_ASSERT( msg[i] == 0 ); } - /* Check we didn't write past the end */ - TEST_ASSERT( output[msg_len] == 0xFF && output[msg_len + 1] == 0xFF ); + /* Check we didn't write past the end (where the original tag is) */ + TEST_ASSERT( memcmp( msg + msg_len, tag, tag_len ) == 0 ); ccm_free( &ctx ); }