From 26d365eb54fd3503562d218a019f28a79369ba07 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 12:22:16 +0100 Subject: [PATCH 01/14] Add parameter validation for CCM --- include/mbedtls/ccm.h | 53 +++---- library/ccm.c | 29 ++++ tests/suites/test_suite_ccm.data | 3 + tests/suites/test_suite_ccm.function | 207 +++++++++++++++++++++++++++ 4 files changed, 267 insertions(+), 25 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index dfb1b5e56..009231e23 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -57,7 +57,6 @@ /* MBEDTLS_ERR_CCM_HW_ACCEL_FAILED is deprecated and should not be used. */ #define MBEDTLS_ERR_CCM_HW_ACCEL_FAILED -0x0011 /**< CCM hardware accelerator failed. */ - #ifdef __cplusplus extern "C" { #endif @@ -85,7 +84,7 @@ mbedtls_ccm_context; * to make references valid, and prepare the context * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). * - * \param ctx The CCM context to initialize. + * \param ctx The CCM context to initialize. Must not be NULL. */ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); @@ -93,9 +92,9 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); * \brief This function initializes the CCM context set in the * \p ctx parameter and sets the encryption key. * - * \param ctx The CCM context to initialize. + * \param ctx The CCM context to initialize. Must not be NULL. * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. + * \param key The encryption key. Must not be NULL. * \param keybits The key size in bits. This must be acceptable by the cipher. * * \return \c 0 on success. @@ -110,7 +109,7 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. + * \param ctx The CCM context to clear. Must not be NULL. */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); @@ -123,19 +122,20 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \p tag = \p output + \p length, and make sure that the * output buffer is at least \p length + \p tag_len wide. * - * \param ctx The CCM context to use for encryption. + * \param ctx The CCM context to use for encryption. Must not be NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). + * \param iv Initialization vector (nonce). Must not be NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. + * \param add The additional data field. Must not be NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. + * \param input The buffer holding the input data. Must not be NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. + * \param tag The buffer holding the authentication field. Must not be + * NULL. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -161,19 +161,20 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * the tag length has to be encoded into the \p iv passed to * this function. * - * \param ctx The CCM context to use for encryption. + * \param ctx The CCM context to use for encryption. Must not be NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). + * \param iv Initialization vector (nonce). Must not be NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. + * \param add The additional data field. Must not be NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. + * \param input The buffer holding the input data. Must not be NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. + * \param tag The buffer holding the authentication field. Must not be + * NULL. * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * @@ -193,19 +194,20 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \brief This function performs a CCM authenticated decryption of a * buffer. * - * \param ctx The CCM context to use for decryption. + * \param ctx The CCM context to use for decryption. Must not be NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). + * \param iv Initialization vector (nonce). Must not be NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. + * \param add The additional data field. Must not be NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. + * \param input The buffer holding the input data. Must not be NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. + * \param tag The buffer holding the authentication field. Must not be + * NULL. * \param tag_len The length of the authentication field in Bytes. * 4, 6, 8, 10, 12, 14 or 16. * @@ -228,19 +230,20 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * this function as \p tag_len. (\p tag needs to be adjusted * accordingly.) * - * \param ctx The CCM context to use for decryption. + * \param ctx The CCM context to use for decryption. Must not be NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). + * \param iv Initialization vector (nonce). Must not be NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. + * \param add The additional data field. Must not be NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. + * \param input The buffer holding the input data. Must not be NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. + * \param tag The buffer holding the authentication field. Must not be + * NULL. * \param tag_len The length of the authentication field in Bytes. * 0, 4, 6, 8, 10, 12, 14 or 16. * diff --git a/library/ccm.c b/library/ccm.c index 90cab8e14..4bb3642da 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -52,6 +52,11 @@ #if !defined(MBEDTLS_CCM_ALT) +#define CCM_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_CCM_BAD_INPUT ) +#define CCM_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + #define CCM_ENCRYPT 0 #define CCM_DECRYPT 1 @@ -60,6 +65,7 @@ */ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) { + CCM_VALIDATE( ctx != NULL ); memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); } @@ -71,6 +77,9 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, int ret; const mbedtls_cipher_info_t *cipher_info; + CCM_VALIDATE_RET( ctx != NULL ); + CCM_VALIDATE_RET( key != NULL ); + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); if( cipher_info == NULL ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); @@ -97,6 +106,7 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) { + CCM_VALIDATE( ctx != NULL ); mbedtls_cipher_free( &ctx->cipher_ctx ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); } @@ -310,6 +320,12 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_len ) { + CCM_VALIDATE_RET( ctx != NULL ); + CCM_VALIDATE_RET( iv != NULL ); + CCM_VALIDATE_RET( add != NULL ); + CCM_VALIDATE_RET( input != NULL ); + CCM_VALIDATE_RET( output != NULL ); + CCM_VALIDATE_RET( tag != NULL ); return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, add, add_len, input, output, tag, tag_len ) ); } @@ -320,6 +336,12 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_len ) { + CCM_VALIDATE_RET( ctx != NULL ); + CCM_VALIDATE_RET( iv != NULL ); + CCM_VALIDATE_RET( add != NULL ); + CCM_VALIDATE_RET( input != NULL ); + CCM_VALIDATE_RET( output != NULL ); + CCM_VALIDATE_RET( tag != NULL ); if( tag_len == 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); @@ -341,6 +363,13 @@ int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, unsigned char i; int diff; + CCM_VALIDATE_RET( ctx != NULL ); + CCM_VALIDATE_RET( iv != NULL ); + CCM_VALIDATE_RET( add != NULL ); + CCM_VALIDATE_RET( input != NULL ); + CCM_VALIDATE_RET( output != NULL ); + CCM_VALIDATE_RET( tag != NULL ); + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, iv, iv_len, add, add_len, input, output, check_tag, tag_len ) ) != 0 ) diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data index a2d877841..a4771b3fe 100644 --- a/tests/suites/test_suite_ccm.data +++ b/tests/suites/test_suite_ccm.data @@ -1,6 +1,9 @@ CCM self test mbedtls_ccm_self_test: +CCM - Invalid parameters +ccm_invalid_param: + CCM init #1 AES-128: OK depends_on:MBEDTLS_AES_C mbedtls_ccm_setkey:MBEDTLS_CIPHER_ID_AES:128:0 diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 9951ca168..95ebe43b5 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -326,3 +326,210 @@ exit: mbedtls_ccm_free( &ctx ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */ +void ccm_invalid_param( ) +{ + struct mbedtls_ccm_context ctx; + unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES; + int valid_len = sizeof(valid_buffer); + int valid_bitlen = valid_len * 8; + + mbedtls_ccm_init( &ctx ); + + /* mbedtls_ccm_init() */ + TEST_INVALID_PARAM( mbedtls_ccm_init( NULL ) ); + + /* mbedtls_ccm_setkey() */ + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_setkey( NULL, valid_cipher, valid_buffer, valid_bitlen ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_setkey( &ctx, valid_cipher, NULL, valid_bitlen ) ); + + /* mbedtls_ccm_encrypt_and_tag() */ + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_encrypt_and_tag( NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_encrypt_and_tag( &ctx, valid_len, + NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + NULL, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + NULL, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, NULL, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + NULL, valid_len ) ); + + /* mbedtls_ccm_star_encrypt_and_tag() */ + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_encrypt_and_tag( NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len, + NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + NULL, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + NULL, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, NULL, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_encrypt_and_tag( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + NULL, valid_len ) ); + + /* mbedtls_ccm_auth_decrypt() */ + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_auth_decrypt( NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_auth_decrypt( &ctx, valid_len, + NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + NULL, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + NULL, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, NULL, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + NULL, valid_len ) ); + + /* mbedtls_ccm_star_auth_decrypt() */ + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_auth_decrypt( NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_auth_decrypt( &ctx, valid_len, + NULL, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + NULL, valid_len, + valid_buffer, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + NULL, valid_buffer, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, NULL, + valid_buffer, valid_len ) ); + TEST_INVALID_PARAM_RET( + MBEDTLS_ERR_CCM_BAD_INPUT, + mbedtls_ccm_star_auth_decrypt( &ctx, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_len, + valid_buffer, valid_buffer, + NULL, valid_len ) ); + + /* mbedtls_ccm_free() */ + TEST_INVALID_PARAM( mbedtls_ccm_free( NULL ) ); + +exit: + mbedtls_ccm_free( &ctx ); + return; +} +/* END_CASE */ From 438448e45fe5082d7123f6dc9d1d61aa7af0ba8f Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 13:11:30 +0100 Subject: [PATCH 02/14] Format NULL occurrences in CCM's Doxygen comments --- include/mbedtls/ccm.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 009231e23..0eb1abe9c 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -84,7 +84,7 @@ mbedtls_ccm_context; * to make references valid, and prepare the context * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). * - * \param ctx The CCM context to initialize. Must not be NULL. + * \param ctx The CCM context to initialize. Must not be \c NULL. */ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); @@ -92,9 +92,9 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); * \brief This function initializes the CCM context set in the * \p ctx parameter and sets the encryption key. * - * \param ctx The CCM context to initialize. Must not be NULL. + * \param ctx The CCM context to initialize. Must not be \c NULL. * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. Must not be NULL. + * \param key The encryption key. Must not be \c NULL. * \param keybits The key size in bits. This must be acceptable by the cipher. * * \return \c 0 on success. @@ -109,7 +109,7 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. Must not be NULL. + * \param ctx The CCM context to clear. Must not be \c NULL. */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); @@ -122,20 +122,20 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \p tag = \p output + \p length, and make sure that the * output buffer is at least \p length + \p tag_len wide. * - * \param ctx The CCM context to use for encryption. Must not be NULL. + * \param ctx The CCM context to use for encryption. Must not be \c NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be NULL. + * \param iv Initialization vector (nonce). Must not be \c NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be NULL. + * \param add The additional data field. Must not be \c NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be NULL. + * \param input The buffer holding the input data. Must not be \c NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. * \param tag The buffer holding the authentication field. Must not be - * NULL. + * \c NULL. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -161,16 +161,16 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * the tag length has to be encoded into the \p iv passed to * this function. * - * \param ctx The CCM context to use for encryption. Must not be NULL. + * \param ctx The CCM context to use for encryption. Must not be \c NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be NULL. + * \param iv Initialization vector (nonce). Must not be \c NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be NULL. + * \param add The additional data field. Must not be \c NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be NULL. + * \param input The buffer holding the input data. Must not be \c NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. * \param tag The buffer holding the authentication field. Must not be @@ -194,16 +194,16 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \brief This function performs a CCM authenticated decryption of a * buffer. * - * \param ctx The CCM context to use for decryption. Must not be NULL. + * \param ctx The CCM context to use for decryption. Must not be \c NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be NULL. + * \param iv Initialization vector (nonce). Must not be \c NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be NULL. + * \param add The additional data field. Must not be \c NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be NULL. + * \param input The buffer holding the input data. Must not be \c NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. * \param tag The buffer holding the authentication field. Must not be @@ -230,16 +230,16 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * this function as \p tag_len. (\p tag needs to be adjusted * accordingly.) * - * \param ctx The CCM context to use for decryption. Must not be NULL. + * \param ctx The CCM context to use for decryption. Must not be \c NULL. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be NULL. + * \param iv Initialization vector (nonce). Must not be \c NULL. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be NULL. + * \param add The additional data field. Must not be \c NULL. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be NULL. + * \param input The buffer holding the input data. Must not be \c NULL. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. * \param tag The buffer holding the authentication field. Must not be From fd42d531ba20f9868397711a3e67d102111c9093 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 14:37:51 +0100 Subject: [PATCH 03/14] Explicitly allow NULL as an argument to mbedtls_ccm_free() --- include/mbedtls/ccm.h | 4 +++- library/ccm.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 0eb1abe9c..6210c1f8c 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -109,7 +109,9 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. Must not be \c NULL. + * \param ctx The CCM context to clear. + * + * \note If ctx is \c NULL, the function has no effect. */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); diff --git a/library/ccm.c b/library/ccm.c index 4bb3642da..ad0d71b00 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -106,7 +106,8 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) { - CCM_VALIDATE( ctx != NULL ); + if( ctx == NULL ) + return; mbedtls_cipher_free( &ctx->cipher_ctx ); mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); } From ff8a0989c80aaaac50213dc7de4530713a9ea79f Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 15:56:55 +0100 Subject: [PATCH 04/14] Allow empty arguments in some CCM functions' parameter validation --- library/ccm.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/ccm.c b/library/ccm.c index ad0d71b00..97eed7bd8 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -323,9 +323,9 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, { CCM_VALIDATE_RET( ctx != NULL ); CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add != NULL ); - CCM_VALIDATE_RET( input != NULL ); - CCM_VALIDATE_RET( output != NULL ); + CCM_VALIDATE_RET( add_len == 0 || add != NULL ); + CCM_VALIDATE_RET( length == 0 || input != NULL ); + CCM_VALIDATE_RET( length == 0 || output != NULL ); CCM_VALIDATE_RET( tag != NULL ); return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, add, add_len, input, output, tag, tag_len ) ); @@ -339,9 +339,9 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, { CCM_VALIDATE_RET( ctx != NULL ); CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add != NULL ); - CCM_VALIDATE_RET( input != NULL ); - CCM_VALIDATE_RET( output != NULL ); + CCM_VALIDATE_RET( add_len == 0 || add != NULL ); + CCM_VALIDATE_RET( length == 0 || input != NULL ); + CCM_VALIDATE_RET( length == 0 || output != NULL ); CCM_VALIDATE_RET( tag != NULL ); if( tag_len == 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); @@ -366,9 +366,9 @@ int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, CCM_VALIDATE_RET( ctx != NULL ); CCM_VALIDATE_RET( iv != NULL ); - CCM_VALIDATE_RET( add != NULL ); - CCM_VALIDATE_RET( input != NULL ); - CCM_VALIDATE_RET( output != NULL ); + CCM_VALIDATE_RET( add_len == 0 || add != NULL ); + CCM_VALIDATE_RET( length == 0 || input != NULL ); + CCM_VALIDATE_RET( length == 0 || output != NULL ); CCM_VALIDATE_RET( tag != NULL ); if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, From f7125348019b60e1a98171a75137867a3810c1d2 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 15:57:19 +0100 Subject: [PATCH 05/14] Add missing validation code in CCM --- library/ccm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/ccm.c b/library/ccm.c index 97eed7bd8..78d04b2e3 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -397,6 +397,13 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len ) { + CCM_VALIDATE_RET( ctx != NULL ); + CCM_VALIDATE_RET( iv != NULL ); + CCM_VALIDATE_RET( add_len == 0 || add != NULL ); + CCM_VALIDATE_RET( length == 0 || input != NULL ); + CCM_VALIDATE_RET( length == 0 || output != NULL ); + CCM_VALIDATE_RET( tag != NULL ); + if( tag_len == 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); From 12f0d5c66d36e855d44f0eee5685c524d6aef760 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 16:25:08 +0100 Subject: [PATCH 06/14] Improve the constraints definition in the doxygen comments in CCM --- include/mbedtls/ccm.h | 99 ++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 35 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 6210c1f8c..b2c57a4ae 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -92,7 +92,8 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); * \brief This function initializes the CCM context set in the * \p ctx parameter and sets the encryption key. * - * \param ctx The CCM context to initialize. Must not be \c NULL. + * \param ctx The CCM context to initialize. Must be an initialized + * context. * \param cipher The 128-bit block cipher to use. * \param key The encryption key. Must not be \c NULL. * \param keybits The key size in bits. This must be acceptable by the cipher. @@ -109,7 +110,7 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. + * \param ctx The CCM context to clear. Must be an initialized context. * * \note If ctx is \c NULL, the function has no effect. */ @@ -124,20 +125,27 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \p tag = \p output + \p length, and make sure that the * output buffer is at least \p length + \p tag_len wide. * - * \param ctx The CCM context to use for encryption. Must not be \c NULL. + * \param ctx The CCM context to use for encryption. Must be an + * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be \c NULL. + * \param iv Initialization vector (nonce). Must be a readable buffer of + * at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be \c NULL. + * \param add The additional data field. If \p add_len is greater than + * zero, \p add must be a readable buffer of at least that + * length. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be \c NULL. - * \param output The buffer holding the output data. - * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. Must not be - * \c NULL. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. Must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -163,20 +171,27 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * the tag length has to be encoded into the \p iv passed to * this function. * - * \param ctx The CCM context to use for encryption. Must not be \c NULL. + * \param ctx The CCM context to use for encryption. Must be an + * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be \c NULL. + * \param iv Initialization vector (nonce). Must be a readable buffer of + * at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be \c NULL. + * \param add The additional data field. If \p add_len is greater than + * zero, \p add must be a readable buffer of at least that + * length. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be \c NULL. - * \param output The buffer holding the output data. - * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. Must not be - * NULL. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. Must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * @@ -196,21 +211,28 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \brief This function performs a CCM authenticated decryption of a * buffer. * - * \param ctx The CCM context to use for decryption. Must not be \c NULL. + * \param ctx The CCM context to use for decryption. Must be an + * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be \c NULL. + * \param iv Initialization vector (nonce). Must be a readable buffer of + * at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be \c NULL. + * \param add The additional data field. If \p add_len is greater than + * zero, \p add must be a readable buffer of at least that + * length. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be \c NULL. - * \param output The buffer holding the output data. - * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. Must not be - * NULL. - * \param tag_len The length of the authentication field in Bytes. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. Must be a + * readable buffer of at least \p tag_len Bytes. + * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * * \return \c 0 on success. This indicates that the message is authentic. @@ -232,20 +254,27 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * this function as \p tag_len. (\p tag needs to be adjusted * accordingly.) * - * \param ctx The CCM context to use for decryption. Must not be \c NULL. + * \param ctx The CCM context to use for decryption. Must be an + * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must not be \c NULL. + * \param iv Initialization vector (nonce). Must be a readable buffer of + * at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. Must not be \c NULL. + * \param add The additional data field. If \p add_len is greater than + * zero, \p add must be a readable buffer of at least that + * length. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. - * \param input The buffer holding the input data. Must not be \c NULL. - * \param output The buffer holding the output data. - * Must be at least \p length Bytes wide. - * \param tag The buffer holding the authentication field. Must not be - * NULL. + * \param input The buffer holding the input data. If \p length is greater + * than zero, \p input must be a readable buffer of at least + * that length. + * \param output The buffer holding the output data. If \p length is greater + * than zero, \p output must be a writable buffer of at least + * that length. + * \param tag The buffer holding the authentication field. Must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field in Bytes. * 0, 4, 6, 8, 10, 12, 14 or 16. * From 508bcd96db210954ef0bc05a373482ff795bcf9a Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 11 Dec 2018 16:52:26 +0100 Subject: [PATCH 07/14] Remove unneeded test for the CCM free function --- tests/suites/test_suite_ccm.function | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 95ebe43b5..188633918 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -525,9 +525,6 @@ void ccm_invalid_param( ) valid_buffer, valid_buffer, NULL, valid_len ) ); - /* mbedtls_ccm_free() */ - TEST_INVALID_PARAM( mbedtls_ccm_free( NULL ) ); - exit: mbedtls_ccm_free( &ctx ); return; From dd63359daee8a0db2aef0889dcd742b289817910 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Wed, 12 Dec 2018 15:26:49 +0100 Subject: [PATCH 08/14] Add tests for valid NULL in ccm_free() --- tests/suites/test_suite_ccm.data | 3 +++ tests/suites/test_suite_ccm.function | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data index a4771b3fe..819b3b71f 100644 --- a/tests/suites/test_suite_ccm.data +++ b/tests/suites/test_suite_ccm.data @@ -4,6 +4,9 @@ mbedtls_ccm_self_test: CCM - Invalid parameters ccm_invalid_param: +CCM - Valid parameters +ccm_valid_param: + CCM init #1 AES-128: OK depends_on:MBEDTLS_AES_C mbedtls_ccm_setkey:MBEDTLS_CIPHER_ID_AES:128:0 diff --git a/tests/suites/test_suite_ccm.function b/tests/suites/test_suite_ccm.function index 188633918..16f9f8e3b 100644 --- a/tests/suites/test_suite_ccm.function +++ b/tests/suites/test_suite_ccm.function @@ -530,3 +530,12 @@ exit: return; } /* END_CASE */ + +/* BEGIN_CASE */ +void ccm_valid_param( ) +{ + TEST_VALID_PARAM( mbedtls_ccm_free( NULL ) ); +exit: + return; +} +/* END_CASE */ From b92f9334e4a102a5e117c39e7900a98a3df9603a Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Thu, 13 Dec 2018 11:13:51 +0100 Subject: [PATCH 09/14] Doxygen comments improvement --- include/mbedtls/ccm.h | 61 ++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index b2c57a4ae..3f3a25ddf 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -84,7 +84,7 @@ mbedtls_ccm_context; * to make references valid, and prepare the context * for mbedtls_ccm_setkey() or mbedtls_ccm_free(). * - * \param ctx The CCM context to initialize. Must not be \c NULL. + * \param ctx The CCM context to initialize. This must not be \c NULL. */ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); @@ -92,10 +92,10 @@ void mbedtls_ccm_init( mbedtls_ccm_context *ctx ); * \brief This function initializes the CCM context set in the * \p ctx parameter and sets the encryption key. * - * \param ctx The CCM context to initialize. Must be an initialized + * \param ctx The CCM context to initialize. This must be an initialized * context. * \param cipher The 128-bit block cipher to use. - * \param key The encryption key. Must not be \c NULL. + * \param key The encryption key. This must not be \c NULL. * \param keybits The key size in bits. This must be acceptable by the cipher. * * \return \c 0 on success. @@ -110,7 +110,8 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. Must be an initialized context. + * \param ctx The CCM context to clear. This must be an initialized + * context. * * \note If ctx is \c NULL, the function has no effect. */ @@ -125,26 +126,26 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \p tag = \p output + \p length, and make sure that the * output buffer is at least \p length + \p tag_len wide. * - * \param ctx The CCM context to use for encryption. Must be an + * \param ctx The CCM context to use for encryption. This must be an * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must be a readable buffer of - * at least \p iv_len Bytes. + * \param iv Initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. + * length. If `pad_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. - * Must be less than 2^16 - 2^8. + * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater * than zero, \p input must be a readable buffer of at least * that length. * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. Must be a + * \param tag The buffer holding the authentication field. This must be a * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. @@ -171,31 +172,31 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * the tag length has to be encoded into the \p iv passed to * this function. * - * \param ctx The CCM context to use for encryption. Must be an + * \param ctx The CCM context to use for encryption. This must be an * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must be a readable buffer of - * at least \p iv_len Bytes. + * \param iv Initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. + * length. If `pad_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. - * Must be less than 2^16 - 2^8. + * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater * than zero, \p input must be a readable buffer of at least * that length. * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. Must be a + * \param tag The buffer holding the authentication field. This must be a * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * - * \warning Passing 0 as \p tag_len means that the message is no + * \warning Passing \c 0 as \p tag_len means that the message is no * longer authenticated. * * \return \c 0 on success. @@ -211,26 +212,26 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \brief This function performs a CCM authenticated decryption of a * buffer. * - * \param ctx The CCM context to use for decryption. Must be an + * \param ctx The CCM context to use for decryption. This must be an * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must be a readable buffer of - * at least \p iv_len Bytes. + * \param iv Initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. + * length. If `pad_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. - * Must be less than 2^16 - 2^8. + * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater * than zero, \p input must be a readable buffer of at least * that length. * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. Must be a + * \param tag The buffer holding the authentication field. This must be a * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. @@ -254,31 +255,31 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * this function as \p tag_len. (\p tag needs to be adjusted * accordingly.) * - * \param ctx The CCM context to use for decryption. Must be an + * \param ctx The CCM context to use for decryption. This must be an * initialized context. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). Must be a readable buffer of - * at least \p iv_len Bytes. + * \param iv Initialization vector (nonce). This must be a readable + * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. + * length. If `pad_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. - * Must be less than 2^16 - 2^8. + * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater * than zero, \p input must be a readable buffer of at least * that length. * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. Must be a + * \param tag The buffer holding the authentication field. This must be a * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field in Bytes. * 0, 4, 6, 8, 10, 12, 14 or 16. * - * \warning Passing 0 as \p tag_len means that the message is no + * \warning Passing \c 0 as \p tag_len means that the message is nos * longer authenticated. * * \return \c 0 on success. From 270a125946e648fb4103f081e59e8e4b6c7f4801 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Thu, 13 Dec 2018 11:14:04 +0100 Subject: [PATCH 10/14] Add a change log entry --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 0ead78009..9f0bb400a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,7 @@ API Changes in favour a new generic error MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA. * Deprecate the Blowfish error MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH in favour of a new generic error MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA. + * Add validation checks for input parameters to functions in the CCM module. New deprecations * Deprecate mbedtls_ctr_drbg_update and mbedtls_hmac_drbg_update From 373a660193f00a9954c907b51fd4c80163c8226f Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Thu, 13 Dec 2018 14:50:17 +0100 Subject: [PATCH 11/14] Fix a documentation typo --- include/mbedtls/ccm.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 3f3a25ddf..21ba098a7 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -136,7 +136,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. If `pad_len == 0`, this may be \c NULL. + * length. If `add_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater @@ -182,7 +182,7 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. If `pad_len == 0`, this may be \c NULL. + * length. If `add_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater @@ -222,7 +222,7 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. If `pad_len == 0`, this may be \c NULL. + * length. If `add_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater @@ -265,7 +265,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. If `pad_len == 0`, this may be \c NULL. + * length. If `add_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater From 9da5d7cd83c89d42b197f9f37667f164202fff4f Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Thu, 13 Dec 2018 17:19:48 +0100 Subject: [PATCH 12/14] Adjust mbedtls_ccm_free() documentation --- include/mbedtls/ccm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 21ba098a7..112da44f3 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -110,8 +110,8 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * \brief This function releases and clears the specified CCM context * and underlying cipher sub-context. * - * \param ctx The CCM context to clear. This must be an initialized - * context. + * \param ctx The CCM context to clear. If this is \c NULL, the function + * has no effect. Otherwise, this must be initialized. * * \note If ctx is \c NULL, the function has no effect. */ From 6adb0574eacee6e7fa8612dc8ee20f9fd2fbceb7 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Tue, 18 Dec 2018 10:22:34 +0100 Subject: [PATCH 13/14] Improve details of CCM parameter validation and documentation --- include/mbedtls/ccm.h | 46 +++++++++++++++++++++++-------------------- library/ccm.c | 8 ++++---- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 112da44f3..20730d891 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -126,10 +126,10 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \p tag = \p output + \p length, and make sure that the * output buffer is at least \p length + \p tag_len wide. * - * \param ctx The CCM context to use for encryption. This must be an - * initialized context. + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). This must be a readable + * \param iv The initialization vector (nonce). This must be a readable * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is @@ -138,15 +138,16 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * zero, \p add must be a readable buffer of at least that * length. If `add_len == 0`, this may be \c NULL. * \param add_len The length of additional data in Bytes. - * This must be less than 2^16 - 2^8. + * This must be less than `2^16 - 2^8`. * \param input The buffer holding the input data. If \p length is greater * than zero, \p input must be a readable buffer of at least * that length. * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. + * \param tag The buffer holding the authentication field. If + * `tag_len > 0`, then this must be a readable buffer of at + * least \p tag_len Bytes. Otherwise, this may be \c NULL. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -172,10 +173,10 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * the tag length has to be encoded into the \p iv passed to * this function. * - * \param ctx The CCM context to use for encryption. This must be an - * initialized context. + * \param ctx The CCM context to use for encryption. This must be + * initialized and bound to a key. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). This must be a readable + * \param iv The initialization vector (nonce). This must be a readable * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is @@ -191,8 +192,9 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. + * \param tag The buffer holding the authentication field. If + * `tag_len > 0`, then this must be a readable buffer of at + * least \p tag_len Bytes. Otherwise, this may be \c NULL. * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * @@ -212,10 +214,10 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \brief This function performs a CCM authenticated decryption of a * buffer. * - * \param ctx The CCM context to use for decryption. This must be an - * initialized context. + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). This must be a readable + * \param iv The initialization vector (nonce). This must be a readable * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is @@ -231,8 +233,9 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. + * \param tag The buffer holding the authentication field. If + * `tag_len > 0`, then this must be a readable buffer of at + * least \p tag_len Bytes. Otherwise, this may be \c NULL. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -255,10 +258,10 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * this function as \p tag_len. (\p tag needs to be adjusted * accordingly.) * - * \param ctx The CCM context to use for decryption. This must be an - * initialized context. + * \param ctx The CCM context to use for decryption. This must be + * initialized and bound to a key. * \param length The length of the input data in Bytes. - * \param iv Initialization vector (nonce). This must be a readable + * \param iv The initialization vector (nonce). This must be a readable * buffer of at least \p iv_len Bytes. * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is @@ -274,8 +277,9 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. This must be a - * readable buffer of at least \p tag_len Bytes. + * \param tag The buffer holding the authentication field. If + * `tag_len > 0`, then this must be a readable buffer of at + * least \p tag_len Bytes. Otherwise, this may be \c NULL. * \param tag_len The length of the authentication field in Bytes. * 0, 4, 6, 8, 10, 12, 14 or 16. * diff --git a/library/ccm.c b/library/ccm.c index 78d04b2e3..01e58b043 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -326,7 +326,7 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, CCM_VALIDATE_RET( add_len == 0 || add != NULL ); CCM_VALIDATE_RET( length == 0 || input != NULL ); CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag != NULL ); + CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, add, add_len, input, output, tag, tag_len ) ); } @@ -342,7 +342,7 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, CCM_VALIDATE_RET( add_len == 0 || add != NULL ); CCM_VALIDATE_RET( length == 0 || input != NULL ); CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag != NULL ); + CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); if( tag_len == 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); @@ -369,7 +369,7 @@ int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, CCM_VALIDATE_RET( add_len == 0 || add != NULL ); CCM_VALIDATE_RET( length == 0 || input != NULL ); CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag != NULL ); + CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, iv, iv_len, add, add_len, @@ -402,7 +402,7 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, CCM_VALIDATE_RET( add_len == 0 || add != NULL ); CCM_VALIDATE_RET( length == 0 || input != NULL ); CCM_VALIDATE_RET( length == 0 || output != NULL ); - CCM_VALIDATE_RET( tag != NULL ); + CCM_VALIDATE_RET( tag_len == 0 || tag != NULL ); if( tag_len == 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); From 247a782668a59d44f817163881bb259eeca5b459 Mon Sep 17 00:00:00 2001 From: k-stachowiak Date: Wed, 19 Dec 2018 13:36:03 +0100 Subject: [PATCH 14/14] Increase strictness of NULL parameter validity in CCM's doxygen --- include/mbedtls/ccm.h | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index 20730d891..3f6b8f670 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -112,8 +112,6 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, * * \param ctx The CCM context to clear. If this is \c NULL, the function * has no effect. Otherwise, this must be initialized. - * - * \note If ctx is \c NULL, the function has no effect. */ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); @@ -136,7 +134,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * 15 - \p iv_len. * \param add The additional data field. If \p add_len is greater than * zero, \p add must be a readable buffer of at least that - * length. If `add_len == 0`, this may be \c NULL. + * length. * \param add_len The length of additional data in Bytes. * This must be less than `2^16 - 2^8`. * \param input The buffer holding the input data. If \p length is greater @@ -145,9 +143,8 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. If - * `tag_len > 0`, then this must be a readable buffer of at - * least \p tag_len Bytes. Otherwise, this may be \c NULL. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -181,9 +178,8 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. If \p add_len is greater than - * zero, \p add must be a readable buffer of at least that - * length. If `add_len == 0`, this may be \c NULL. + * \param add The additional data field. This must be a readable buffer of + * at least \p add_len Bytes. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater @@ -192,9 +188,8 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. If - * `tag_len > 0`, then this must be a readable buffer of at - * least \p tag_len Bytes. Otherwise, this may be \c NULL. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 0, 4, 6, 8, 10, 12, 14 or 16. * @@ -222,9 +217,8 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. If \p add_len is greater than - * zero, \p add must be a readable buffer of at least that - * length. If `add_len == 0`, this may be \c NULL. + * \param add The additional data field. This must be a readable buffer + * of at least that \p add_len Bytes.. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater @@ -233,9 +227,8 @@ int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. If - * `tag_len > 0`, then this must be a readable buffer of at - * least \p tag_len Bytes. Otherwise, this may be \c NULL. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * @@ -266,9 +259,8 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, * or 13. The length L of the message length field is * 15 - \p iv_len. - * \param add The additional data field. If \p add_len is greater than - * zero, \p add must be a readable buffer of at least that - * length. If `add_len == 0`, this may be \c NULL. + * \param add The additional data field. This must be a readable buffer of + * at least that \p add_len Bytes. * \param add_len The length of additional data in Bytes. * This must be less than 2^16 - 2^8. * \param input The buffer holding the input data. If \p length is greater @@ -277,9 +269,8 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, * \param output The buffer holding the output data. If \p length is greater * than zero, \p output must be a writable buffer of at least * that length. - * \param tag The buffer holding the authentication field. If - * `tag_len > 0`, then this must be a readable buffer of at - * least \p tag_len Bytes. Otherwise, this may be \c NULL. + * \param tag The buffer holding the authentication field. This must be a + * readable buffer of at least \p tag_len Bytes. * \param tag_len The length of the authentication field in Bytes. * 0, 4, 6, 8, 10, 12, 14 or 16. *