From 8a8492bcd4a910057598de28cac3eefc017f396a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 18:17:32 +0100 Subject: [PATCH 01/13] SSL test programs: stuff RNG context into a struct Group the random generation context (entropy and DRBG) into a struct. This is in preparation for unifying the common RNG-related code of ssl_client2 and ssl_server2, then generalizing that code to support methods other than entropy+CTR_DRBG. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 21 ++++++++++----------- programs/ssl/ssl_server2.c | 27 +++++++++++++-------------- programs/ssl/ssl_test_lib.h | 8 ++++++++ 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 0f0e93e07c..d34b4b07e6 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -686,8 +686,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; #endif - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; + rng_context_t rng; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_ssl_session saved_session; @@ -742,7 +741,7 @@ int main( int argc, char *argv[] ) mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) ); - mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_ctr_drbg_init( &rng.drbg ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); @@ -1534,12 +1533,12 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); - mbedtls_entropy_init( &entropy ); + mbedtls_entropy_init( &rng.entropy ); if (opt.reproducible) { srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, - &entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, dummy_entropy, + &rng.entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -1549,8 +1548,8 @@ int main( int argc, char *argv[] ) } else { - if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, - &entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, mbedtls_entropy_func, + &rng.entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -1904,7 +1903,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); @@ -3024,8 +3023,8 @@ exit: mbedtls_ssl_session_free( &saved_session ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - mbedtls_ctr_drbg_free( &ctr_drbg ); - mbedtls_entropy_free( &entropy ); + mbedtls_ctr_drbg_free( &rng.drbg ); + mbedtls_entropy_free( &rng.entropy ); if( session_data != NULL ) mbedtls_platform_zeroize( session_data, session_data_len ); mbedtls_free( session_data ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 952769895b..303bec9d5b 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1282,8 +1282,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; #endif - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; + rng_context_t rng; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; #if defined(MBEDTLS_TIMING_C) @@ -1377,7 +1376,7 @@ int main( int argc, char *argv[] ) mbedtls_net_init( &listen_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); - mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_ctr_drbg_init( &rng.drbg ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &srvcert ); @@ -2293,12 +2292,12 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); - mbedtls_entropy_init( &entropy ); + mbedtls_entropy_init( &rng.entropy ); if (opt.reproducible) { srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy, - &entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, dummy_entropy, + &rng.entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -2308,8 +2307,8 @@ int main( int argc, char *argv[] ) } else { - if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, - &entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, mbedtls_entropy_func, + &rng.entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -2706,7 +2705,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); #if defined(MBEDTLS_SSL_CACHE_C) @@ -2725,7 +2724,7 @@ int main( int argc, char *argv[] ) if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED ) { if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx, - mbedtls_ctr_drbg_random, &ctr_drbg, + mbedtls_ctr_drbg_random, &rng.drbg, MBEDTLS_CIPHER_AES_256_GCM, opt.ticket_timeout ) ) != 0 ) { @@ -2747,7 +2746,7 @@ int main( int argc, char *argv[] ) if( opt.cookies > 0 ) { if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx, - mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) + mbedtls_ctr_drbg_random, &rng.drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret ); goto exit; @@ -2900,7 +2899,7 @@ int main( int argc, char *argv[] ) - opt.async_private_error : opt.async_private_error ); ssl_async_keys.f_rng = mbedtls_ctr_drbg_random; - ssl_async_keys.p_rng = &ctr_drbg; + ssl_async_keys.p_rng = &rng.drbg; mbedtls_ssl_conf_async_private_cb( &conf, sign, decrypt, @@ -3998,8 +3997,8 @@ exit: mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - mbedtls_ctr_drbg_free( &ctr_drbg ); - mbedtls_entropy_free( &entropy ); + mbedtls_ctr_drbg_free( &rng.drbg ); + mbedtls_entropy_free( &rng.entropy ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_free( &cache ); diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index 031c872bdb..9f22ee4d5a 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -128,6 +128,14 @@ mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); int dummy_entropy( void *data, unsigned char *output, size_t len ); +/** A context for random generation. + */ +typedef struct +{ + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context drbg; +} rng_context_t; + #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) int ca_callback( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates ); From b3715eb86e1df07c3581cc451de872c571eeb6d5 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 18:21:37 +0100 Subject: [PATCH 02/13] SSL test programs: prepare to unify common code In preparation for unifying the common RNG-related code of ssl_client2 and ssl_server2, make it possible to copy-paste that code out of these programs' main() functions: * Replaces reads of the non-unifiable structure opt by reads of a separate variable. * Replace references to the local variable rng by a pointer. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 24 +++++++++++++----------- programs/ssl/ssl_server2.c | 30 ++++++++++++++++-------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index d34b4b07e6..a19b297129 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -686,7 +686,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; #endif - rng_context_t rng; + rng_context_t rng_context; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_ssl_session saved_session; @@ -741,7 +741,9 @@ int main( int argc, char *argv[] ) mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) ); - mbedtls_ctr_drbg_init( &rng.drbg ); + rng_context_t *rng = &rng_context; + mbedtls_ctr_drbg_init( &rng->drbg ); + mbedtls_entropy_init( &rng->entropy ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); @@ -1533,12 +1535,12 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); - mbedtls_entropy_init( &rng.entropy ); - if (opt.reproducible) + int reproducible = opt.reproducible; + if ( reproducible ) { srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, dummy_entropy, - &rng.entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy, + &rng->entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -1548,8 +1550,8 @@ int main( int argc, char *argv[] ) } else { - if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, mbedtls_entropy_func, - &rng.entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func, + &rng->entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -1903,7 +1905,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng->drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); @@ -3023,8 +3025,8 @@ exit: mbedtls_ssl_session_free( &saved_session ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - mbedtls_ctr_drbg_free( &rng.drbg ); - mbedtls_entropy_free( &rng.entropy ); + mbedtls_ctr_drbg_free( &rng->drbg ); + mbedtls_entropy_free( &rng->entropy ); if( session_data != NULL ) mbedtls_platform_zeroize( session_data, session_data_len ); mbedtls_free( session_data ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 303bec9d5b..bceca54080 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1282,7 +1282,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; #endif - rng_context_t rng; + rng_context_t rng_context; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; #if defined(MBEDTLS_TIMING_C) @@ -1376,7 +1376,9 @@ int main( int argc, char *argv[] ) mbedtls_net_init( &listen_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); - mbedtls_ctr_drbg_init( &rng.drbg ); + rng_context_t *rng = &rng_context; + mbedtls_ctr_drbg_init( &rng->drbg ); + mbedtls_entropy_init( &rng->entropy ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &srvcert ); @@ -2292,12 +2294,12 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); - mbedtls_entropy_init( &rng.entropy ); - if (opt.reproducible) + int reproducible = opt.reproducible; + if ( reproducible ) { srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, dummy_entropy, - &rng.entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy, + &rng->entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -2307,8 +2309,8 @@ int main( int argc, char *argv[] ) } else { - if( ( ret = mbedtls_ctr_drbg_seed( &rng.drbg, mbedtls_entropy_func, - &rng.entropy, (const unsigned char *) pers, + if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func, + &rng->entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -2705,7 +2707,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng->drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); #if defined(MBEDTLS_SSL_CACHE_C) @@ -2724,7 +2726,7 @@ int main( int argc, char *argv[] ) if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED ) { if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx, - mbedtls_ctr_drbg_random, &rng.drbg, + mbedtls_ctr_drbg_random, &rng->drbg, MBEDTLS_CIPHER_AES_256_GCM, opt.ticket_timeout ) ) != 0 ) { @@ -2746,7 +2748,7 @@ int main( int argc, char *argv[] ) if( opt.cookies > 0 ) { if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx, - mbedtls_ctr_drbg_random, &rng.drbg ) ) != 0 ) + mbedtls_ctr_drbg_random, &rng->drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret ); goto exit; @@ -2899,7 +2901,7 @@ int main( int argc, char *argv[] ) - opt.async_private_error : opt.async_private_error ); ssl_async_keys.f_rng = mbedtls_ctr_drbg_random; - ssl_async_keys.p_rng = &rng.drbg; + ssl_async_keys.p_rng = &rng->drbg; mbedtls_ssl_conf_async_private_cb( &conf, sign, decrypt, @@ -3997,8 +3999,8 @@ exit: mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - mbedtls_ctr_drbg_free( &rng.drbg ); - mbedtls_entropy_free( &rng.entropy ); + mbedtls_ctr_drbg_free( &rng->drbg ); + mbedtls_entropy_free( &rng->entropy ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_free( &cache ); From daa94c4ff501c87c60018102fff3878f04eacee1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 18:38:27 +0100 Subject: [PATCH 03/13] SSL test programs: move RNG common code to ssl_test_lib This commit is deliberately arranged to minimize code changes. Subsequent commits will clean up the resulting code. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 32 ++++---------------------- programs/ssl/ssl_server2.c | 32 ++++---------------------- programs/ssl/ssl_test_lib.c | 46 +++++++++++++++++++++++++++++++++++++ programs/ssl/ssl_test_lib.h | 32 +++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 57 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index a19b297129..9250b100af 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -742,8 +742,7 @@ int main( int argc, char *argv[] ) mbedtls_ssl_config_init( &conf ); memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) ); rng_context_t *rng = &rng_context; - mbedtls_ctr_drbg_init( &rng->drbg ); - mbedtls_entropy_init( &rng->entropy ); + rng_init( rng ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); @@ -1536,30 +1535,8 @@ int main( int argc, char *argv[] ) fflush( stdout ); int reproducible = opt.reproducible; - if ( reproducible ) - { - srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy, - &rng->entropy, (const unsigned char *) pers, - strlen( pers ) ) ) != 0 ) - { - mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", - (unsigned int) -ret ); - goto exit; - } - } - else - { - if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func, - &rng->entropy, (const unsigned char *) pers, - strlen( pers ) ) ) != 0 ) - { - mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", - (unsigned int) -ret ); - goto exit; - } - } - + if( rng_seed( rng, reproducible, pers ) != 0 ) + goto exit; mbedtls_printf( " ok\n" ); #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -3025,8 +3002,7 @@ exit: mbedtls_ssl_session_free( &saved_session ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - mbedtls_ctr_drbg_free( &rng->drbg ); - mbedtls_entropy_free( &rng->entropy ); + rng_free( rng ); if( session_data != NULL ) mbedtls_platform_zeroize( session_data, session_data_len ); mbedtls_free( session_data ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index bceca54080..0c4c77bd59 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1377,8 +1377,7 @@ int main( int argc, char *argv[] ) mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); rng_context_t *rng = &rng_context; - mbedtls_ctr_drbg_init( &rng->drbg ); - mbedtls_entropy_init( &rng->entropy ); + rng_init( rng ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &srvcert ); @@ -2295,30 +2294,8 @@ int main( int argc, char *argv[] ) fflush( stdout ); int reproducible = opt.reproducible; - if ( reproducible ) - { - srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy, - &rng->entropy, (const unsigned char *) pers, - strlen( pers ) ) ) != 0 ) - { - mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", - (unsigned int) -ret ); - goto exit; - } - } - else - { - if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func, - &rng->entropy, (const unsigned char *) pers, - strlen( pers ) ) ) != 0 ) - { - mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", - (unsigned int) -ret ); - goto exit; - } - } - + if( rng_seed( rng, reproducible, pers ) != 0 ) + goto exit; mbedtls_printf( " ok\n" ); #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -3999,8 +3976,7 @@ exit: mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - mbedtls_ctr_drbg_free( &rng->drbg ); - mbedtls_entropy_free( &rng->entropy ); + rng_free( rng ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_free( &cache ); diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c index 22453c19f8..bbb4d4a8d9 100644 --- a/programs/ssl/ssl_test_lib.c +++ b/programs/ssl/ssl_test_lib.c @@ -61,6 +61,52 @@ int dummy_entropy( void *data, unsigned char *output, size_t len ) return( ret ); } +void rng_init( rng_context_t *rng ) +{ + mbedtls_ctr_drbg_init( &rng->drbg ); + mbedtls_entropy_init( &rng->entropy ); +} + +int rng_seed( rng_context_t *rng, int reproducible, const char *pers ) +{ + int ret = 0; + + if ( reproducible ) + { + srand( 1 ); + if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy, + &rng->entropy, (const unsigned char *) pers, + strlen( pers ) ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", + (unsigned int) -ret ); + goto exit; + } + } + else + { + if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func, + &rng->entropy, (const unsigned char *) pers, + strlen( pers ) ) ) != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", + (unsigned int) -ret ); + goto exit; + } + } + + + return( 0 ); +exit: + return( 1 ); +} + +void rng_free( rng_context_t *rng ) +{ + mbedtls_ctr_drbg_free( &rng->drbg ); + mbedtls_entropy_free( &rng->entropy ); +} + #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) int ca_callback( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates ) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index 9f22ee4d5a..db08a46e67 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -128,7 +128,7 @@ mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); int dummy_entropy( void *data, unsigned char *output, size_t len ); -/** A context for random generation. +/** A context for random number generation (RNG). */ typedef struct { @@ -136,6 +136,36 @@ typedef struct mbedtls_ctr_drbg_context drbg; } rng_context_t; +/** Initialize the RNG. + * + * This function only initializes the memory used by the RNG context. + * Before using the RNG, it must be seeded with rng_seed(). + */ +void rng_init( rng_context_t *rng ); + +/* Seed the random number generator. + * + * \param rng The RNG context to use. It must have been initialized + * with rng_init(). + * \param reproducible If zero, seed the RNG from entropy. + * If nonzero, use a fixed seed, so that the program + * will produce the same sequence of random numbers + * each time it is invoked. + * \param pers A null-terminated string. Different values for this + * string cause the RNG to emit different output for + * the same seed. + * + * return 0 on success, a negative value on error. + */ +int rng_seed( rng_context_t *rng, int reproducible, const char *pers ); + +/** Deinitialize the RNG. Free any embedded resource. + * + * \param rng The RNG context to deinitialize. It must have been + * initialized with rng_init(). + */ +void rng_free( rng_context_t *rng ); + #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) int ca_callback( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates ); From f1cb75fe13970fe406533077040ce72464aed712 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 18:46:01 +0100 Subject: [PATCH 04/13] Local cleanups following the code move No behavior change. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 12 +++++------- programs/ssl/ssl_server2.c | 18 ++++++++---------- programs/ssl/ssl_test_lib.c | 38 +++++++++++++------------------------ programs/ssl/ssl_test_lib.h | 2 -- 4 files changed, 26 insertions(+), 44 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 9250b100af..70beb9dc50 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -686,7 +686,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; #endif - rng_context_t rng_context; + rng_context_t rng; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_ssl_session saved_session; @@ -741,8 +741,7 @@ int main( int argc, char *argv[] ) mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); memset( &saved_session, 0, sizeof( mbedtls_ssl_session ) ); - rng_context_t *rng = &rng_context; - rng_init( rng ); + rng_init( &rng ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); @@ -1534,8 +1533,7 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); - int reproducible = opt.reproducible; - if( rng_seed( rng, reproducible, pers ) != 0 ) + if( rng_seed( &rng, opt.reproducible, pers ) != 0 ) goto exit; mbedtls_printf( " ok\n" ); @@ -1882,7 +1880,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng->drbg ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); @@ -3002,7 +3000,7 @@ exit: mbedtls_ssl_session_free( &saved_session ); mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - rng_free( rng ); + rng_free( &rng ); if( session_data != NULL ) mbedtls_platform_zeroize( session_data, session_data_len ); mbedtls_free( session_data ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 0c4c77bd59..ba4dabc3ba 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1282,7 +1282,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default; #endif - rng_context_t rng_context; + rng_context_t rng; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; #if defined(MBEDTLS_TIMING_C) @@ -1376,8 +1376,7 @@ int main( int argc, char *argv[] ) mbedtls_net_init( &listen_fd ); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); - rng_context_t *rng = &rng_context; - rng_init( rng ); + rng_init( &rng ); #if defined(MBEDTLS_X509_CRT_PARSE_C) mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &srvcert ); @@ -2293,8 +2292,7 @@ int main( int argc, char *argv[] ) mbedtls_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); - int reproducible = opt.reproducible; - if( rng_seed( rng, reproducible, pers ) != 0 ) + if( rng_seed( &rng, opt.reproducible, pers ) != 0 ) goto exit; mbedtls_printf( " ok\n" ); @@ -2684,7 +2682,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng->drbg ); + mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); #if defined(MBEDTLS_SSL_CACHE_C) @@ -2703,7 +2701,7 @@ int main( int argc, char *argv[] ) if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED ) { if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx, - mbedtls_ctr_drbg_random, &rng->drbg, + mbedtls_ctr_drbg_random, &rng.drbg, MBEDTLS_CIPHER_AES_256_GCM, opt.ticket_timeout ) ) != 0 ) { @@ -2725,7 +2723,7 @@ int main( int argc, char *argv[] ) if( opt.cookies > 0 ) { if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx, - mbedtls_ctr_drbg_random, &rng->drbg ) ) != 0 ) + mbedtls_ctr_drbg_random, &rng.drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret ); goto exit; @@ -2878,7 +2876,7 @@ int main( int argc, char *argv[] ) - opt.async_private_error : opt.async_private_error ); ssl_async_keys.f_rng = mbedtls_ctr_drbg_random; - ssl_async_keys.p_rng = &rng->drbg; + ssl_async_keys.p_rng = &rng.drbg; mbedtls_ssl_conf_async_private_cb( &conf, sign, decrypt, @@ -3976,7 +3974,7 @@ exit: mbedtls_ssl_free( &ssl ); mbedtls_ssl_config_free( &conf ); - rng_free( rng ); + rng_free( &rng ); #if defined(MBEDTLS_SSL_CACHE_C) mbedtls_ssl_cache_free( &cache ); diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c index bbb4d4a8d9..e3c95ccf7c 100644 --- a/programs/ssl/ssl_test_lib.c +++ b/programs/ssl/ssl_test_lib.c @@ -46,7 +46,7 @@ mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ) return 0x5af2a056; } -int dummy_entropy( void *data, unsigned char *output, size_t len ) +static int dummy_entropy( void *data, unsigned char *output, size_t len ) { size_t i; int ret; @@ -69,36 +69,24 @@ void rng_init( rng_context_t *rng ) int rng_seed( rng_context_t *rng, int reproducible, const char *pers ) { - int ret = 0; + int ( *f_entropy )( void *, unsigned char *, size_t ) = + ( reproducible ? dummy_entropy : mbedtls_entropy_func ); if ( reproducible ) - { srand( 1 ); - if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, dummy_entropy, - &rng->entropy, (const unsigned char *) pers, - strlen( pers ) ) ) != 0 ) - { - mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", - (unsigned int) -ret ); - goto exit; - } - } - else - { - if( ( ret = mbedtls_ctr_drbg_seed( &rng->drbg, mbedtls_entropy_func, - &rng->entropy, (const unsigned char *) pers, - strlen( pers ) ) ) != 0 ) - { - mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", - (unsigned int) -ret ); - goto exit; - } - } + int ret = mbedtls_ctr_drbg_seed( &rng->drbg, + f_entropy, &rng->entropy, + (const unsigned char *) pers, + strlen( pers ) ); + if( ret != 0 ) + { + mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", + (unsigned int) -ret ); + return( ret ); + } return( 0 ); -exit: - return( 1 ); } void rng_free( rng_context_t *rng ) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index db08a46e67..e1948a2ea0 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -126,8 +126,6 @@ void my_debug( void *ctx, int level, mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); -int dummy_entropy( void *data, unsigned char *output, size_t len ); - /** A context for random number generation (RNG). */ typedef struct From 535fb378702f8954794849e323a7d969625d9e00 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 18:59:46 +0100 Subject: [PATCH 05/13] SSL test programs: abstract CTR_DRBG away In ssl_client2 and ssl_server2, to generate random data, go through a level of indirection provided by ssl_test_lib. This way the programs don't depend on a particular choice of RNG implementation, and only ssl_test_lib.{h,c} explicitly reference CTR_DRBG. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 2 +- programs/ssl/ssl_server2.c | 10 +++++----- programs/ssl/ssl_test_lib.c | 6 ++++++ programs/ssl/ssl_test_lib.h | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 70beb9dc50..ff0a34986d 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -1880,7 +1880,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); + mbedtls_ssl_conf_rng( &conf, rng_get, &rng ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index ba4dabc3ba..d95b1b7e31 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -2682,7 +2682,7 @@ int main( int argc, char *argv[] ) #endif #endif } - mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &rng.drbg ); + mbedtls_ssl_conf_rng( &conf, rng_get, &rng ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); #if defined(MBEDTLS_SSL_CACHE_C) @@ -2701,7 +2701,7 @@ int main( int argc, char *argv[] ) if( opt.tickets == MBEDTLS_SSL_SESSION_TICKETS_ENABLED ) { if( ( ret = mbedtls_ssl_ticket_setup( &ticket_ctx, - mbedtls_ctr_drbg_random, &rng.drbg, + rng_get, &rng, MBEDTLS_CIPHER_AES_256_GCM, opt.ticket_timeout ) ) != 0 ) { @@ -2723,7 +2723,7 @@ int main( int argc, char *argv[] ) if( opt.cookies > 0 ) { if( ( ret = mbedtls_ssl_cookie_setup( &cookie_ctx, - mbedtls_ctr_drbg_random, &rng.drbg ) ) != 0 ) + rng_get, &rng ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret ); goto exit; @@ -2875,8 +2875,8 @@ int main( int argc, char *argv[] ) ssl_async_keys.inject_error = ( opt.async_private_error < 0 ? - opt.async_private_error : opt.async_private_error ); - ssl_async_keys.f_rng = mbedtls_ctr_drbg_random; - ssl_async_keys.p_rng = &rng.drbg; + ssl_async_keys.f_rng = rng_get; + ssl_async_keys.p_rng = &rng; mbedtls_ssl_conf_async_private_cb( &conf, sign, decrypt, diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c index e3c95ccf7c..84553df71b 100644 --- a/programs/ssl/ssl_test_lib.c +++ b/programs/ssl/ssl_test_lib.c @@ -95,6 +95,12 @@ void rng_free( rng_context_t *rng ) mbedtls_entropy_free( &rng->entropy ); } +int rng_get( void *p_rng, unsigned char *output, size_t output_len ) +{ + rng_context_t *rng = p_rng; + return( mbedtls_ctr_drbg_random( &rng->drbg, output, output_len ) ); +} + #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) int ca_callback( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates ) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index e1948a2ea0..344cd28fd3 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -164,6 +164,21 @@ int rng_seed( rng_context_t *rng, int reproducible, const char *pers ); */ void rng_free( rng_context_t *rng ); +/** Generate random data. + * + * This function is suitable for use as the \c f_rng argument to Mbed TLS + * library functions. + * + * \param p_rng The CTR_DRBG context. This must be a pointer to a + * #rng_context_t structure. + * \param output The buffer to fill. + * \param output_len The length of the buffer in bytes. + * + * \return \c 0 on success. + * \return An Mbed TLS error code on error. + */ +int rng_get( void *p_rng, unsigned char *output, size_t output_len ); + #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) int ca_callback( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates ); From ba74904c48bfa9d0d4b787577ae90026597d6ee0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 20:02:03 +0100 Subject: [PATCH 06/13] SSL test programs: support HMAC_DRBG Support HMAC_DRBG in ssl_client2 and ssl_server2, in addition to CTR_DRBG. CTR_DRBG is still used if present, but it's now possible to run the SSL test programs with CTR_DRBG disabled. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_test_lib.c | 38 +++++++++++++++++++++++++++++++++++++ programs/ssl/ssl_test_lib.h | 16 +++++++++++++--- tests/scripts/all.sh | 16 ++++++++++++---- 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c index 84553df71b..46cea144c1 100644 --- a/programs/ssl/ssl_test_lib.c +++ b/programs/ssl/ssl_test_lib.c @@ -63,7 +63,14 @@ static int dummy_entropy( void *data, unsigned char *output, size_t len ) void rng_init( rng_context_t *rng ) { +#if defined(MBEDTLS_CTR_DRBG_C) mbedtls_ctr_drbg_init( &rng->drbg ); +#elif defined(MBEDTLS_HMAC_DRBG_C) + mbedtls_hmac_drbg_init( &rng->drbg ); +#else +#error "No DRBG available" +#endif + mbedtls_entropy_init( &rng->entropy ); } @@ -75,10 +82,28 @@ int rng_seed( rng_context_t *rng, int reproducible, const char *pers ) if ( reproducible ) srand( 1 ); +#if defined(MBEDTLS_CTR_DRBG_C) int ret = mbedtls_ctr_drbg_seed( &rng->drbg, f_entropy, &rng->entropy, (const unsigned char *) pers, strlen( pers ) ); +#elif defined(MBEDTLS_HMAC_DRBG_C) +#if defined(MBEDTLS_SHA256_C) + const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; +#elif defined(MBEDTLS_SHA512_C) + const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA512; +#else +#error "No message digest available for HMAC_DRBG" +#endif + int ret = mbedtls_hmac_drbg_seed( &rng->drbg, + mbedtls_md_info_from_type( md_type ), + f_entropy, &rng->entropy, + (const unsigned char *) pers, + strlen( pers ) ); +#else +#error "No DRBG available" +#endif + if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", @@ -91,14 +116,27 @@ int rng_seed( rng_context_t *rng, int reproducible, const char *pers ) void rng_free( rng_context_t *rng ) { +#if defined(MBEDTLS_CTR_DRBG_C) mbedtls_ctr_drbg_free( &rng->drbg ); +#elif defined(MBEDTLS_HMAC_DRBG_C) + mbedtls_hmac_drbg_free( &rng->drbg ); +#else +#error "No DRBG available" +#endif + mbedtls_entropy_free( &rng->entropy ); } int rng_get( void *p_rng, unsigned char *output, size_t output_len ) { rng_context_t *rng = p_rng; +#if defined(MBEDTLS_CTR_DRBG_C) return( mbedtls_ctr_drbg_random( &rng->drbg, output, output_len ) ); +#elif defined(MBEDTLS_HMAC_DRBG_C) + return( mbedtls_hmac_drbg_random( &rng->drbg, output, output_len ) ); +#else +#error "No DRBG available" +#endif } #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index 344cd28fd3..2e91730556 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -43,17 +43,20 @@ #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE #endif -#if !defined(MBEDTLS_CTR_DRBG_C) || \ - !defined(MBEDTLS_ENTROPY_C) || \ +#if !defined(MBEDTLS_ENTROPY_C) || \ !defined(MBEDTLS_NET_C) || \ !defined(MBEDTLS_SSL_TLS_C) || \ defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) #define MBEDTLS_SSL_TEST_IMPOSSIBLE \ - "MBEDTLS_CTR_DRBG_C and/or " \ "MBEDTLS_ENTROPY_C and/or " \ "MBEDTLS_NET_C and/or " \ "MBEDTLS_SSL_TLS_C not defined, " \ "and/or MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined.\n" +#elif !( defined(MBEDTLS_CTR_DRBG_C) || \ + defined(MBEDTLS_HMAC_DRBG_C) && ( defined(MBEDTLS_SHA256_C) || \ + defined(MBEDTLS_SHA512_C) ) ) +#define MBEDTLS_SSL_TEST_IMPOSSIBLE \ + "Neither MBEDTLS_CTR_DRBG_C, nor MBEDTLS_HMAC_DRBG_C and a supported hash defined.\n" #else #undef MBEDTLS_SSL_TEST_IMPOSSIBLE @@ -65,6 +68,7 @@ #include "mbedtls/ssl.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" +#include "mbedtls/hmac_drbg.h" #include "mbedtls/certs.h" #include "mbedtls/x509.h" #include "mbedtls/error.h" @@ -131,7 +135,13 @@ mbedtls_time_t dummy_constant_time( mbedtls_time_t* time ); typedef struct { mbedtls_entropy_context entropy; +#if defined(MBEDTLS_CTR_DRBG_C) mbedtls_ctr_drbg_context drbg; +#elif defined(MBEDTLS_HMAC_DRBG_C) + mbedtls_hmac_drbg_context drbg; +#else +#error "No DRBG available" +#endif } rng_context_t; /** Initialize the RNG. diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index a016732f49..43a6fdd80f 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -919,10 +919,17 @@ component_test_no_ctr_drbg () { CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . make - msg "test: no CTR_DRBG" + msg "test: Full minus CTR_DRBG - main suites" make test - # no ssl-opt.sh/compat.sh as they all depend on CTR_DRBG so far + # In this configuration, the TLS test programs use HMAC_DRBG. + # The SSL tests are slow, so run a small subset, just enough to get + # confidence that the SSL code copes with HMAC_DRBG. + msg "test: Full minus CTR_DRBG - ssl-opt.sh (subset)" + if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private.*delay=\|tickets enabled on server' + + msg "test: Full minus CTR_DRBG - compat.sh (subset)" + if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA PSK' -V NO -p OpenSSL } component_test_no_hmac_drbg () { @@ -954,7 +961,7 @@ component_test_psa_external_rng_no_drbg () { msg "test: PSA_CRYPTO_EXTERNAL_RNG minus *_DRBG" make test - # No ssl-opt.sh/compat.sh because they require CTR_DRBG. + # no SSL tests as they all depend on having a DRBG } component_test_psa_external_rng_use_psa_crypto () { @@ -968,7 +975,8 @@ component_test_psa_external_rng_use_psa_crypto () { msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG" make test - # No ssl-opt.sh/compat.sh because they require CTR_DRBG. + msg "test: full + PSA_CRYPTO_EXTERNAL_RNG + USE_PSA_CRYPTO minus CTR_DRBG" + if_build_succeeded tests/ssl-opt.sh -f 'Default\|opaque' } component_test_ecp_no_internal_rng () { From a222434952f066e87612c1c6ce06ca9e23fc514b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 19 Nov 2020 22:14:34 +0100 Subject: [PATCH 07/13] Test SSL with non-deterministic ECDSA In component_test_no_hmac_drbg, the fact that HMAC_DRBG is disabled doesn't affect the SSL code, but the fact that deterministic ECDSA is disabled does. So run some ECDSA-related SSL tests. Signed-off-by: Gilles Peskine --- tests/scripts/all.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 43a6fdd80f..676c804493 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -941,11 +941,21 @@ component_test_no_hmac_drbg () { CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . make - msg "test: no HMAC_DRBG" + msg "test: Full minus HMAC_DRBG - main suites" make test - # No ssl-opt.sh/compat.sh as they never use HMAC_DRBG so far, - # so there's little value in running those lengthy tests here. + # Normally our ECDSA implementation uses deterministic ECDSA. But since + # HMAC_DRBG is disabled in this configuration, randomized ECDSA is used + # instead. + # Test SSL with non-deterministic ECDSA. Only test features that + # might be affected by how ECDSA signature is performed. + msg "test: Full minus HMAC_DRBG - ssl-opt.sh (subset)" + if_build_succeeded tests/ssl-opt.sh -f 'Default\|SSL async private: sign' + + # To save time, only test one protocol version, since this part of + # the protocol is identical in (D)TLS up to 1.2. + msg "test: Full minus HMAC_DRBG - compat.sh (ECDSA)" + if_build_succeeded tests/compat.sh -m tls1_2 -t 'ECDSA' } component_test_psa_external_rng_no_drbg () { From 2146211204991c3586df89d912bf77370f64fac0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 13 Jan 2021 23:53:09 +0100 Subject: [PATCH 08/13] SSL test programs: enable the PSA test external RNG Currently, MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is tested with a dummy insecure implementation of mbedtls_psa_external_get_random. This function needs to be explicitly enabled at runtime. This needs to happen when the PSA external RNG is used, which currently is the case in SSL test programs only when MBEDTLS_USE_PSA_CRYPTO is enabled. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 3 +++ programs/ssl/ssl_server2.c | 3 +++ programs/ssl/ssl_test_lib.h | 8 ++++++++ 3 files changed, 14 insertions(+) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index ff0a34986d..56df7dfe10 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -760,6 +760,9 @@ int main( int argc, char *argv[] ) ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; goto exit; } +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + mbedtls_test_enable_insecure_external_rng( ); +#endif #endif if( argc == 0 ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index d95b1b7e31..da7f0a6ab5 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1412,6 +1412,9 @@ int main( int argc, char *argv[] ) ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; goto exit; } +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + mbedtls_test_enable_insecure_external_rng( ); +#endif #endif #if !defined(_WIN32) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index 2e91730556..99609daf96 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -189,6 +189,14 @@ void rng_free( rng_context_t *rng ); */ int rng_get( void *p_rng, unsigned char *output, size_t output_len ); +#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +/* The test implementation of the PSA external RNG is insecure. When + * MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, before using any PSA crypto + * function that makes use of an RNG, you must call + * mbedtls_test_enable_insecure_external_rng(). */ +#include +#endif + #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) int ca_callback( void *data, mbedtls_x509_crt const *child, mbedtls_x509_crt **candidates ); From e1d51bd99df27262bd0ac0a90aa9b7731052516f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 20 Jan 2021 19:47:23 +0100 Subject: [PATCH 09/13] Depend on all test headers when building tests There were explicit dependencies on header files for some test suites, dating back from when only a few test suites depended on anything in tests/include. The noted dependencies were still correct, but now that tests/include is more populated, they were only the tip of the iceberg. Just keep it simple and depend on all the headers. Signed-off-by: Gilles Peskine --- tests/Makefile | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index b9c55257b3..7196310342 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -84,7 +84,7 @@ MBEDTLS_TEST_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/drivers/*.c)) mbedtls_test: $(MBEDTLS_TEST_OBJS) -TEST_OBJS_DEPS = +TEST_OBJS_DEPS = $(wildcard include/test/*.h include/test/*/*.h) ifdef RECORD_PSA_STATUS_COVERAGE_LOG TEST_OBJS_DEPS += include/test/instrument_record_status.h endif @@ -130,12 +130,6 @@ $(BINARIES): %$(EXEXT): %.c $(MBEDLIBS) $(TEST_OBJS_DEPS) $(MBEDTLS_TEST_OBJS) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(MBEDTLS_TEST_OBJS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -# Some test suites require additional header files. -$(filter test_suite_psa_crypto%, $(BINARIES)): include/test/psa_crypto_helpers.h -$(addprefix embedded_,$(filter test_suite_psa_crypto%, $(APPS))): embedded_%: TESTS/mbedtls/%/psa_crypto_helpers.h -$(filter test_suite_psa_%, $(BINARIES)): include/test/psa_helpers.h -$(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: TESTS/mbedtls/%/psa_helpers.h - clean: ifndef WINDOWS rm -rf $(BINARIES) *.c *.datax TESTS @@ -192,6 +186,7 @@ endif endef $(foreach app, $(APPS), $(foreach file, $(notdir $(wildcard include/test/*.h)), \ $(eval $(call copy_header_to_target,$(app),$(file))))) +$(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: $(patsubst TESTS/mbedtls/%, include/test/%, $(wildcard include/test/*. include/test/*/*.h)) ifdef RECORD_PSA_STATUS_COVERAGE_LOG include/test/instrument_record_status.h: ../include/psa/crypto.h Makefile From 1af872d23b51d89f303d3633a49e0d50db616ee9 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 20 Jan 2021 20:02:01 +0100 Subject: [PATCH 10/13] Move the fake PSA external RNG to its own header and source files Move the declaration of the functions needed to use the test implementation of mbedtls_psa_external_get_random() to a new header file. Before, they were declared in tests/include/test/psa_crypto_helpers.h, but this header file can't be included in sample programs because it also includes headers from the library directory which is not on the include path for sample programs. This fixes the build of the sample programs when MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG and MBEDTLS_USE_PSA_CRYPTO are enabled. Move the implementation of the functions to a separate .c file as well. This isn't strictly necessary, but makes the structure of the source code easier to understand. Signed-off-by: Gilles Peskine --- programs/ssl/ssl_test_lib.h | 2 +- .../include/test/fake_external_rng_for_test.h | 56 +++++++++++++++++++ tests/include/test/helpers.h | 4 ++ tests/include/test/psa_crypto_helpers.h | 26 --------- tests/src/fake_external_rng_for_test.c | 56 +++++++++++++++++++ tests/src/psa_crypto_helpers.c | 32 ----------- visualc/VS2010/mbedTLS.vcxproj | 2 + 7 files changed, 119 insertions(+), 59 deletions(-) create mode 100644 tests/include/test/fake_external_rng_for_test.h create mode 100644 tests/src/fake_external_rng_for_test.c diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index 99609daf96..abad5a089c 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -194,7 +194,7 @@ int rng_get( void *p_rng, unsigned char *output, size_t output_len ); * MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, before using any PSA crypto * function that makes use of an RNG, you must call * mbedtls_test_enable_insecure_external_rng(). */ -#include +#include #endif #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) diff --git a/tests/include/test/fake_external_rng_for_test.h b/tests/include/test/fake_external_rng_for_test.h new file mode 100644 index 0000000000..faeef22e86 --- /dev/null +++ b/tests/include/test/fake_external_rng_for_test.h @@ -0,0 +1,56 @@ +/* + * Insecure but standalone implementation of mbedtls_psa_external_get_random(). + * Only for use in tests! + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FAKE_EXTERNAL_RNG_FOR_TEST_H +#define FAKE_EXTERNAL_RNG_FOR_TEST_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +/** Enable the insecure implementation of mbedtls_psa_external_get_random(). + * + * The insecure implementation of mbedtls_psa_external_get_random() is + * disabled by default. + * + * When MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled and the test + * helpers are linked into a program, you must enable this before running any + * code that uses the PSA subsystem to generate random data (including internal + * random generation for purposes such as blinding when the random generation + * is routed through PSA). + * + * You can enable and disable it at any time, regardless of the state + * of the PSA subsystem. You may disable it temporarily to simulate a + * depleted entropy source. + */ +void mbedtls_test_enable_insecure_external_rng( void ); + +/** Disable the insecure implementation of mbedtls_psa_external_get_random(). + * + * See mbedtls_test_enable_insecure_external_rng(). + */ +void mbedtls_test_disable_insecure_external_rng( void ); +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + +#endif /* FAKE_EXTERNAL_RNG_FOR_TEST_H */ diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h index 2c7b179abb..ce8a1e2857 100644 --- a/tests/include/test/helpers.h +++ b/tests/include/test/helpers.h @@ -190,4 +190,8 @@ void* mbedtls_test_param_failed_get_state_buf( void ); void mbedtls_test_param_failed_reset_state( void ); #endif /* MBEDTLS_CHECK_PARAMS */ +#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +#include "test/fake_external_rng_for_test.h" +#endif + #endif /* TEST_HELPERS_H */ diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index b8eb4aa5d4..b97263d590 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -63,32 +63,6 @@ const char *mbedtls_test_helper_is_psa_leaking( void ); -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -/** Enable the insecure implementation of mbedtls_psa_external_get_random(). - * - * The insecure implementation of mbedtls_psa_external_get_random() is - * disabled by default. - * - * When MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled and the test - * helpers are linked into a program, you must enable this before running any - * code that uses the PSA subsystem to generate random data (including internal - * random generation for purposes such as blinding when the random generation - * is routed through PSA). - * - * You can enable and disable it at any time, regardless of the state - * of the PSA subsystem. You may disable it temporarily to simulate a - * depleted entropy source. - */ -void mbedtls_test_enable_insecure_external_rng( void ); - -/** Disable the insecure implementation of mbedtls_psa_external_get_random(). - * - * See mbedtls_test_enable_insecure_external_rng(). - */ -void mbedtls_test_disable_insecure_external_rng( void ); -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - - #if defined(RECORD_PSA_STATUS_COVERAGE_LOG) psa_status_t mbedtls_test_record_status( psa_status_t status, const char *func, diff --git a/tests/src/fake_external_rng_for_test.c b/tests/src/fake_external_rng_for_test.c new file mode 100644 index 0000000000..98b3fe0610 --- /dev/null +++ b/tests/src/fake_external_rng_for_test.c @@ -0,0 +1,56 @@ +/** \file psa_crypto_helpers.c + * + * \brief Helper functions to test PSA crypto functionality. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +#include +#include + +static int test_insecure_external_rng_enabled = 0; + +void mbedtls_test_enable_insecure_external_rng( void ) +{ + test_insecure_external_rng_enabled = 1; +} + +void mbedtls_test_disable_insecure_external_rng( void ) +{ + test_insecure_external_rng_enabled = 0; +} + +psa_status_t mbedtls_psa_external_get_random( + mbedtls_psa_external_random_context_t *context, + uint8_t *output, size_t output_size, size_t *output_length ) +{ + (void) context; + + if( !test_insecure_external_rng_enabled ) + return( PSA_ERROR_INSUFFICIENT_ENTROPY ); + + /* This implementation is for test purposes only! + * Use the libc non-cryptographic random generator. */ + mbedtls_test_rnd_std_rand( NULL, output, output_size ); + *output_length = output_size; + return( PSA_SUCCESS ); +} +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ diff --git a/tests/src/psa_crypto_helpers.c b/tests/src/psa_crypto_helpers.c index 00098574ec..cb79a225c1 100644 --- a/tests/src/psa_crypto_helpers.c +++ b/tests/src/psa_crypto_helpers.c @@ -69,36 +69,4 @@ psa_status_t mbedtls_test_record_status( psa_status_t status, } #endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */ -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) -#include - -static int test_insecure_external_rng_enabled = 0; - -void mbedtls_test_enable_insecure_external_rng( void ) -{ - test_insecure_external_rng_enabled = 1; -} - -void mbedtls_test_disable_insecure_external_rng( void ) -{ - test_insecure_external_rng_enabled = 0; -} - -psa_status_t mbedtls_psa_external_get_random( - mbedtls_psa_external_random_context_t *context, - uint8_t *output, size_t output_size, size_t *output_length ) -{ - (void) context; - - if( !test_insecure_external_rng_enabled ) - return( PSA_ERROR_INSUFFICIENT_ENTROPY ); - - /* This implementation is for test purposes only! - * Use the libc non-cryptographic random generator. */ - mbedtls_test_rnd_std_rand( NULL, output, output_size ); - *output_length = output_size; - return( PSA_SUCCESS ); -} -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ - #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 100c3138a5..78832eb6ca 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -233,6 +233,7 @@ + @@ -348,6 +349,7 @@ + From 94ad831f8e6ed76324efad75bb8d762bf57d904a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 25 Jan 2021 13:42:28 +0100 Subject: [PATCH 11/13] Add comments to some endif guards Signed-off-by: Gilles Peskine --- programs/ssl/ssl_client2.c | 4 ++-- programs/ssl/ssl_server2.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 56df7dfe10..876555d931 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -762,8 +762,8 @@ int main( int argc, char *argv[] ) } #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) mbedtls_test_enable_insecure_external_rng( ); -#endif -#endif +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ if( argc == 0 ) { diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index da7f0a6ab5..57c053ce9e 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -1414,8 +1414,8 @@ int main( int argc, char *argv[] ) } #if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) mbedtls_test_enable_insecure_external_rng( ); -#endif -#endif +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #if !defined(_WIN32) /* Abort cleanly on SIGTERM and SIGINT */ From da9529f3e04195482eef0a39c88c294498e48673 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 25 Jan 2021 13:42:42 +0100 Subject: [PATCH 12/13] Update copypasta Signed-off-by: Gilles Peskine --- programs/ssl/ssl_test_lib.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/ssl/ssl_test_lib.h b/programs/ssl/ssl_test_lib.h index abad5a089c..861e82a004 100644 --- a/programs/ssl/ssl_test_lib.h +++ b/programs/ssl/ssl_test_lib.h @@ -179,8 +179,8 @@ void rng_free( rng_context_t *rng ); * This function is suitable for use as the \c f_rng argument to Mbed TLS * library functions. * - * \param p_rng The CTR_DRBG context. This must be a pointer to a - * #rng_context_t structure. + * \param p_rng The random generator context. This must be a pointer to + * a #rng_context_t structure. * \param output The buffer to fill. * \param output_len The length of the buffer in bytes. * From 75829a42965d0b0792dd7a5298ae23370d9a76c8 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 25 Jan 2021 13:46:14 +0100 Subject: [PATCH 13/13] Explain the explicit dependency on instrument_record_status.h Signed-off-by: Gilles Peskine --- tests/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Makefile b/tests/Makefile index 7196310342..d11d904415 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -86,6 +86,9 @@ mbedtls_test: $(MBEDTLS_TEST_OBJS) TEST_OBJS_DEPS = $(wildcard include/test/*.h include/test/*/*.h) ifdef RECORD_PSA_STATUS_COVERAGE_LOG +# Explicitly depend on this header because on a clean copy of the source tree, +# it doesn't exist yet and must be generated as part of the build, and +# therefore the wildcard enumeration above doesn't include it. TEST_OBJS_DEPS += include/test/instrument_record_status.h endif