diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index c91ca58b3..9a3aba0d3 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -248,9 +248,12 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, * \param additional The data to update the state with. * \param add_len Length of \p additional data. * + * \return \c 0 on success. + * \return An error from the underlying AES cipher on failure. */ -void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t add_len ); +int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ); /** * \brief This function updates a CTR_DRBG instance with additional @@ -290,6 +293,35 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng, int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ); + +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief This function updates the state of the CTR_DRBG context. + * + * \deprecated Superseded by mbedtls_ctr_drbg_update_ret() + * in 2.16.0. + * + * \note If \p add_len is greater than + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT, only the first + * #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT Bytes are used. + * The remaining Bytes are silently discarded. + * + * \param ctx The CTR_DRBG context. + * \param additional The data to update the state with. + * \param add_len Length of \p additional data. + */ +MBEDTLS_DEPRECATED void mbedtls_ctr_drbg_update( + mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ); +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ + #if defined(MBEDTLS_FS_IO) /** * \brief This function writes a seed file. diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index 559538121..a264dedb0 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -331,24 +331,39 @@ exit: * and with outputs * ctx = initial_working_state */ -void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, - const unsigned char *additional, size_t add_len ) +int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ) { unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; + int ret; - if( add_len > 0 ) - { - /* MAX_INPUT would be more logical here, but we have to match - * block_cipher_df()'s limits since we can't propagate errors */ - if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) - add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; + if( add_len == 0 ) + return( 0 ); - block_cipher_df( add_input, additional, add_len ); - ctr_drbg_update_internal( ctx, add_input ); - mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); - } + if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 ) + goto exit; + if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 ) + goto exit; + +exit: + mbedtls_platform_zeroize( add_input, sizeof( add_input ) ); + return( ret ); } +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, + size_t add_len ) +{ + /* MAX_INPUT would be more logical here, but we have to match + * block_cipher_df()'s limits since we can't propagate errors */ + if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) + add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; + (void) mbedtls_ctr_drbg_update_ret( ctx, additional, add_len ); +} +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2) * mbedtls_ctr_drbg_reseed(ctx, additional, len) * implements @@ -573,7 +588,7 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char if( fread( buf, 1, n, f ) != n ) ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; else - mbedtls_ctr_drbg_update( ctx, buf, n ); + ret = mbedtls_ctr_drbg_update_ret( ctx, buf, n ); fclose( f ); diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index f10e98aa5..4a97826f6 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -244,9 +244,11 @@ void ctr_drbg_entropy_usage( ) } TEST_ASSERT( last_idx == test_offset_idx ); - /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT) - * (just make sure it doesn't cause memory corruption) */ - mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) ); + /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT). + * Make sure it's detected as an error and doesn't cause memory + * corruption. */ + TEST_ASSERT( mbedtls_ctr_drbg_update_ret( + &ctx, entropy, sizeof( entropy ) ) != 0 ); /* Now enable PR, so the next few calls should all reseed */ mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );