diff --git a/include/mbedtls/cmac.h b/include/mbedtls/cmac.h index fed337d5c..b94b6edcc 100644 --- a/include/mbedtls/cmac.h +++ b/include/mbedtls/cmac.h @@ -27,6 +27,8 @@ #define MBEDTLS_ERR_CMAC_BAD_INPUT -0x0011 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_CMAC_VERIFY_FAILED -0x0013 /**< Verification failed. */ +#define MBEDTLS_ERR_CMAC_ALLOC_FAILED -0x0015 /**< Memory Allocation failed. */ + #ifdef __cplusplus extern "C" { @@ -83,7 +85,7 @@ void mbedtls_cmac_free( mbedtls_cmac_context *ctx ); * \param tag buffer for holding the generated tag * \param tag_len length of the tag to generate in bytes * Must be 4, 6, 8 if cipher block size is 64 - * Must be 4, 6, 8 0, 14 or 16 if cipher block size is 128 + * Must be 4, 6, 8 , 10, 12, 14 or 16 if cipher block size is 128 * * \return 0 if successful */ @@ -100,7 +102,7 @@ int mbedtls_cmac_generate( mbedtls_cmac_context *ctx, * \param tag buffer holding the tag to verify * \param tag_len length of the tag to verify in bytes * Must be 4, 6, 8 if cipher block size is 64 - * Must be 4, 6, 8 0, 14 or 16 if cipher block size is 128 + * Must be 4, 6, 8 , 10, 12, 14 or 16 if cipher block size is 128 * \return 0 if successful and authenticated * MBEDTLS_ERR_CMAC_VERIFY_FAILED if tag does not match */ diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 703233ae9..6e3905d86 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -66,7 +66,7 @@ * PBKDF2 1 0x007C-0x007C * HMAC_DRBG 4 0x0003-0x0009 * CCM 2 0x000D-0x000F - * CMAC 2 0x0011-0x0013 + * CMAC 3 0x0011-0x0015 * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors diff --git a/library/cmac.c b/library/cmac.c index 477e35f98..39ebb8709 100644 --- a/library/cmac.c +++ b/library/cmac.c @@ -121,7 +121,7 @@ static int cmac_multiply_by_u( unsigned char *output, */ static int cmac_generate_subkeys( mbedtls_cmac_context *ctx ) { - int ret, keybytes; + int ret; unsigned char *L; size_t olen, block_size; @@ -129,7 +129,11 @@ static int cmac_generate_subkeys( mbedtls_cmac_context *ctx ) block_size = ctx->cipher_ctx.cipher_info->block_size; L = mbedtls_calloc( block_size, sizeof( unsigned char ) ); - + if( L == NULL) + { + ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED; + goto exit; + } /* Calculate Ek(0) */ memset( L, 0, block_size ); if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, @@ -147,7 +151,8 @@ static int cmac_generate_subkeys( mbedtls_cmac_context *ctx ) goto exit; exit: - mbedtls_zeroize( L, sizeof( L ) ); + if( L != NULL ) + mbedtls_zeroize( L, sizeof( L ) ); free( L ); return( ret ); } @@ -160,7 +165,7 @@ int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx, const unsigned char *key, unsigned int keybits ) { - int ret, blocksize; + int ret; const mbedtls_cipher_info_t *cipher_info; cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, @@ -171,6 +176,9 @@ int mbedtls_cmac_setkey( mbedtls_cmac_context *ctx, ctx->K1 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) ); ctx->K2 = mbedtls_calloc( cipher_info->block_size, sizeof( unsigned char ) ); + if(ctx->K1 == NULL || ctx->K2 == NULL ) + return MBEDTLS_ERR_CMAC_ALLOC_FAILED; + mbedtls_cipher_free( &ctx->cipher_ctx ); if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) @@ -242,7 +250,9 @@ do { \ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, \ state, block_size, \ state, &olen ) ) != 0 ) \ - return( ret ); \ + { \ + goto exit; \ + } \ } while( 0 ) /* @@ -256,8 +266,8 @@ int mbedtls_cmac_generate( mbedtls_cmac_context *ctx, unsigned char *state; unsigned char *M_last; - int n, i, j, ret, needs_padding; - size_t olen, block_size; + int n, j, ret, needs_padding; + size_t olen, block_size, i; ret = 0; @@ -266,12 +276,21 @@ int mbedtls_cmac_generate( mbedtls_cmac_context *ctx, state = mbedtls_calloc( block_size, sizeof( unsigned char ) ); M_last = mbedtls_calloc( block_size, sizeof( unsigned char ) ); + if( state == NULL || M_last == NULL ) + { + ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED; + goto exit; + } + /* * Check in_len requirements: SP800-38B A * 4 is a worst case bottom limit */ if( tag_len < 4 || tag_len > block_size || tag_len % 2 != 0 ) - return( MBEDTLS_ERR_CMAC_BAD_INPUT ); + { + ret = MBEDTLS_ERR_CMAC_BAD_INPUT; + goto exit; + } if( in_len == 0 ) needs_padding = 1; @@ -324,6 +343,11 @@ int mbedtls_cmac_verify( mbedtls_cmac_context *ctx, check_tag = mbedtls_calloc( ctx->cipher_ctx.cipher_info->block_size, sizeof( unsigned char ) ); + if(check_tag == NULL) + { + ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED; + goto exit; + } if( ( ret = mbedtls_cmac_generate( ctx, input, in_len, check_tag, tag_len ) ) != 0 ) @@ -427,7 +451,7 @@ static const unsigned char test_message[] = { #ifdef MBEDTLS_AES_C /* Truncation point of message for AES CMAC tests */ -static const size_t aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { +static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { 0, 16, 40, @@ -435,7 +459,7 @@ static const size_t aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { }; /* AES 128 CMAC Test Data */ -static const unsigned char aes_128_key[] = { +static const unsigned char aes_128_key[16] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; @@ -469,7 +493,7 @@ static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BL }; /* AES 192 CMAC Test Data */ -static const unsigned char aes_192_key[] = { +static const unsigned char aes_192_key[24] = { 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b @@ -504,7 +528,7 @@ static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BL }; /* AES 256 CMAC Test Data */ -static const unsigned char aes_256_key[] = { +static const unsigned char aes_256_key[32] = { 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, @@ -542,7 +566,7 @@ static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][AES_BL #ifdef MBEDTLS_DES_C /* Truncation point of message for 3DES CMAC tests */ -static const size_t des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { +static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { 0, 8, 20, @@ -550,7 +574,7 @@ static const size_t des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { }; /* 3DES 2 Key CMAC Test Data */ -static const unsigned char des3_2key_key[] = { +static const unsigned char des3_2key_key[24] = { 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5, 0x8a, 0x3d, 0x10, 0xba, 0x80, 0x57, 0x0d, 0x38, 0x4c, 0xf1, 0x51, 0x34, 0xa2, 0x85, 0x0d, 0xd5 @@ -563,7 +587,7 @@ static const unsigned char des3_2key_subkeys[2][8] = { 0x1d, 0x9e, 0x6e, 0x7d, 0xae, 0x35, 0xf5, 0xc5 } }; -static const unsigned char T_3des_2key[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = { +static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = { { 0xbd, 0x2e, 0xbf, 0x9a, 0x3b, 0xa0, 0x03, 0x61 }, @@ -579,7 +603,7 @@ static const unsigned char T_3des_2key[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = }; /* 3DES 3 Key CMAC Test Data */ -static const unsigned char des3_3key_key[] = { +static const unsigned char des3_3key_key[24] = { 0x8a, 0xa8, 0x3b, 0xf8, 0xcb, 0xda, 0x10, 0x62, 0x0b, 0xc1, 0xbf, 0x19, 0xfb, 0xb6, 0xcd, 0x58, 0xbc, 0x31, 0x3d, 0x4a, 0x37, 0x1c, 0xa8, 0xb5 @@ -592,7 +616,7 @@ static const unsigned char des3_3key_subkeys[2][8] = { 0x23, 0x31, 0xd3, 0xa6, 0x29, 0xcc, 0xa6, 0xa5 } }; -static const unsigned char T_3des_3key[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = { +static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][DES3_BLOCK_SIZE] = { { 0xb7, 0xa6, 0x88, 0xe1, 0x22, 0xff, 0xaf, 0x95 }, @@ -648,11 +672,11 @@ static const unsigned char PRFT[NB_PRF_TESTS][16] = { #endif /* MBEDTLS_AES_C */ int test_cmac_with_cipher( int verbose, - const unsigned char* testname, + char* testname, const unsigned char* key, int keybits, const unsigned char* messages, - size_t message_lengths[4], + const unsigned int message_lengths[4], const unsigned char* subkeys, const unsigned char* expected_result, mbedtls_cipher_id_t cipher_id, @@ -664,6 +688,11 @@ int test_cmac_with_cipher( int verbose, unsigned char* tag; tag = mbedtls_calloc( block_size, sizeof( unsigned char ) ); + if( tag == NULL ){ + ret = MBEDTLS_ERR_CMAC_ALLOC_FAILED; + goto exit; + } + mbedtls_cmac_init( &ctx ); if( ( ret = mbedtls_cmac_setkey( &ctx, cipher_id, key, keybits ) ) != 0 ) @@ -714,7 +743,7 @@ int test_cmac_with_cipher( int verbose, } #ifdef MBEDTLS_AES_C -int test_aes128_cmac_prf( verbose ) { +int test_aes128_cmac_prf( int verbose ) { int i; int ret; unsigned char tag[16]; @@ -749,8 +778,8 @@ int mbedtls_cmac_self_test( int verbose ) 128, test_message, aes_message_lengths, - aes_128_subkeys, - aes_128_expected_result, + (const unsigned char*) aes_128_subkeys, + (const unsigned char*) aes_128_expected_result, MBEDTLS_CIPHER_ID_AES, AES_BLOCK_SIZE ) !=0 ) ) { @@ -758,29 +787,29 @@ int mbedtls_cmac_self_test( int verbose ) } if( ( ret = test_cmac_with_cipher( verbose, - "AES 192", - aes_192_key, - 192, - test_message, - aes_message_lengths, - aes_192_subkeys, - aes_192_expected_result, - MBEDTLS_CIPHER_ID_AES, - AES_BLOCK_SIZE ) !=0 ) ) + "AES 192", + aes_192_key, + 192, + test_message, + aes_message_lengths, + (const unsigned char*) aes_192_subkeys, + (const unsigned char*) aes_192_expected_result, + MBEDTLS_CIPHER_ID_AES, + AES_BLOCK_SIZE ) !=0 ) ) { return( ret ); } if( ( ret = test_cmac_with_cipher ( verbose, - "AES 256", - aes_256_key, - 256, - test_message, - aes_message_lengths, - aes_256_subkeys, - aes_256_expected_result, - MBEDTLS_CIPHER_ID_AES, - AES_BLOCK_SIZE ) !=0 ) ) + "AES 256", + aes_256_key, + 256, + test_message, + aes_message_lengths, + (const unsigned char*) aes_256_subkeys, + (const unsigned char*) aes_256_expected_result, + MBEDTLS_CIPHER_ID_AES, + AES_BLOCK_SIZE ) !=0 ) ) { return( ret ); } @@ -788,29 +817,29 @@ int mbedtls_cmac_self_test( int verbose ) #ifdef MBEDTLS_DES_C if( ( ret = test_cmac_with_cipher( verbose, - "3DES 2 key", - des3_2key_key, - 192, - test_message, - des3_message_lengths, - des3_2key_subkeys, - T_3des_2key, - MBEDTLS_CIPHER_ID_3DES, - DES3_BLOCK_SIZE ) !=0 ) ) + "3DES 2 key", + des3_2key_key, + 192, + test_message, + des3_message_lengths, + (const unsigned char*) des3_2key_subkeys, + (const unsigned char*) des3_2key_expected_result, + MBEDTLS_CIPHER_ID_3DES, + DES3_BLOCK_SIZE ) !=0 ) ) { return( ret ); } if( ( ret = test_cmac_with_cipher( verbose, - "3DES 3 key", - des3_3key_key, - 192, - test_message, - des3_message_lengths, - des3_3key_subkeys, - T_3des_3key, - MBEDTLS_CIPHER_ID_3DES, - DES3_BLOCK_SIZE ) !=0 ) ) + "3DES 3 key", + des3_3key_key, + 192, + test_message, + des3_message_lengths, + (const unsigned char*) des3_3key_subkeys, + (const unsigned char*) des3_3key_expected_result, + MBEDTLS_CIPHER_ID_3DES, + DES3_BLOCK_SIZE ) !=0 ) ) { return( ret ); } diff --git a/library/error.c b/library/error.c index 8c38cf294..7ec8420e9 100644 --- a/library/error.c +++ b/library/error.c @@ -587,6 +587,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "CMAC - Bad input parameters to function" ); if( use_ret == -(MBEDTLS_ERR_CMAC_VERIFY_FAILED) ) mbedtls_snprintf( buf, buflen, "CMAC - Verification failed" ); + if( use_ret == -(MBEDTLS_ERR_CMAC_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "CMAC - Failed to allocate memory" ); #endif /* MBEDTLS_CMAC_C */ #if defined(MBEDTLS_CTR_DRBG_C) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 17fdb2128..74eed598e 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -278,7 +278,7 @@ int main( int argc, char *argv[] ) suites_tested++; #endif -#if defined(MBEDTLS_CMAC_C) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CMAC_C) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) ) if( ( ret = mbedtls_cmac_self_test( v ) ) != 0 ) return( ret ); #endif