From 3178d1a997b4a2c7b706f1537005f8e2b54a4fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 12 Dec 2018 13:05:00 +0100 Subject: [PATCH] Add param validation for mbedtls_aes_crypt_cbc() --- include/mbedtls/aes.h | 6 +++- library/aes.c | 8 ++++++ tests/suites/test_suite_aes.function | 41 +++++++++++++++++++++++++-- tests/suites/test_suite_aes.rest.data | 8 +++--- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h index 90d5bba26..0f8934f72 100644 --- a/include/mbedtls/aes.h +++ b/include/mbedtls/aes.h @@ -275,7 +275,7 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, * mbedtls_aes_setkey_enc() or mbedtls_aes_setkey_dec() must be called * before the first call to this API with the same context. * - * \note This function operates on aligned blocks, that is, the input size + * \note This function operates on full blocks, that is, the input size * must be a multiple of the AES block size of 16 Bytes. * * \note Upon exit, the content of the IV is updated so that you can @@ -287,13 +287,17 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, * * * \param ctx The AES context to use for encryption or decryption. + * It must be initialized and bound to a key. * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or * #MBEDTLS_AES_DECRYPT. * \param length The length of the input data in Bytes. This must be a * multiple of the block size (16 Bytes). * \param iv Initialization vector (updated after use). + * It must be a readable and writeable buffer of 16 Bytes. * \param input The buffer holding the input data. + * It must be readable and of size \p length. * \param output The buffer holding the output data. + * It must be writeable and of size \p length. * * \return \c 0 on success. * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH diff --git a/library/aes.c b/library/aes.c index 9f2074483..2da86c713 100644 --- a/library/aes.c +++ b/library/aes.c @@ -1049,6 +1049,14 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, int i; unsigned char temp[16]; + AES_VALIDATE_RET( ctx != NULL ); + AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT || + mode == MBEDTLS_AES_DECRYPT ); + AES_VALIDATE_RET( iv != NULL ); + AES_VALIDATE_RET( input != NULL ); + AES_VALIDATE_RET( output != NULL ); + + if( length % 16 ) return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); diff --git a/tests/suites/test_suite_aes.function b/tests/suites/test_suite_aes.function index 0d0e51519..d21a41dd5 100644 --- a/tests/suites/test_suite_aes.function +++ b/tests/suites/test_suite_aes.function @@ -372,7 +372,7 @@ exit: /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */ -void aes_invalid_param( ) +void aes_check_params( ) { mbedtls_aes_context aes_ctx; #if defined(MBEDTLS_CIPHER_MODE_XTS) @@ -422,17 +422,54 @@ void aes_invalid_param( ) TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA, mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, in, NULL ) ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA, + mbedtls_aes_crypt_cbc( NULL, + MBEDTLS_AES_ENCRYPT, 16, + out, in, out ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA, + mbedtls_aes_crypt_cbc( &aes_ctx, + 42, 16, + out, in, out ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA, + mbedtls_aes_crypt_cbc( &aes_ctx, + MBEDTLS_AES_ENCRYPT, 16, + NULL, in, out ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA, + mbedtls_aes_crypt_cbc( &aes_ctx, + MBEDTLS_AES_ENCRYPT, 16, + out, NULL, out ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_AES_BAD_INPUT_DATA, + mbedtls_aes_crypt_cbc( &aes_ctx, + MBEDTLS_AES_ENCRYPT, 16, + out, in, NULL ) ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ } /* END_CASE */ /* BEGIN_CASE */ -void aes_valid_param( ) +void aes_misc_params( ) { + mbedtls_aes_context aes_ctx; + const unsigned char in[16] = { 0 }; + unsigned char out[16]; + /* These calls accept NULL */ TEST_VALID_PARAM( mbedtls_aes_free( NULL ) ); #if defined(MBEDTLS_CIPHER_MODE_XTS) TEST_VALID_PARAM( mbedtls_aes_xts_free( NULL ) ); #endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + TEST_ASSERT( mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_ENCRYPT, + 15, out, in, out ) + == MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); + TEST_ASSERT( mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_ENCRYPT, + 17, out, in, out ) + == MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); +#endif + } /* END_CASE */ diff --git a/tests/suites/test_suite_aes.rest.data b/tests/suites/test_suite_aes.rest.data index a5d843de4..6a76b43eb 100644 --- a/tests/suites/test_suite_aes.rest.data +++ b/tests/suites/test_suite_aes.rest.data @@ -10,11 +10,11 @@ aes_encrypt_cbc:"000000000000000000000000000000000000000000000000000000000000000 AES-256-CBC Decrypt (Invalid input length) aes_decrypt_cbc:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"623a52fcea5d443e48d9181ab32c74":"":MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -AES - Invalid parameters -aes_invalid_param: +AES - Optional Parameter Validation (MBEDTLS_CHECK_PARAMS) +aes_check_params: -AES - Valid parameters -aes_valid_param: +AES - Mandatory Parameter Validation and Valid Parameters +aes_misc_params: AES Selftest depends_on:MBEDTLS_SELF_TEST