Merge pull request #4020 from gilles-peskine-arm/ssl_test_lib-hmac_drg

Support HMAC_DRBG in SSL test programs
This commit is contained in:
Ronald Cron 2021-01-29 08:58:23 +01:00 committed by GitHub
commit 0426e2545d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 324 additions and 145 deletions

View file

@ -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 );
rng_init( &rng );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init( &cacert );
mbedtls_x509_crt_init( &clicert );
@ -761,7 +760,10 @@ int main( int argc, char *argv[] )
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
#endif
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
mbedtls_test_enable_insecure_external_rng( );
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( argc == 0 )
{
@ -1534,31 +1536,8 @@ int main( int argc, char *argv[] )
mbedtls_printf( "\n . Seeding the random number generator..." );
fflush( stdout );
mbedtls_entropy_init( &entropy );
if (opt.reproducible)
{
srand( 1 );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy,
&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( &ctr_drbg, mbedtls_entropy_func,
&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, opt.reproducible, pers ) != 0 )
goto exit;
mbedtls_printf( " ok\n" );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -1904,7 +1883,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, rng_get, &rng );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout );
@ -3024,8 +3003,7 @@ 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 );
rng_free( &rng );
if( session_data != NULL )
mbedtls_platform_zeroize( session_data, session_data_len );
mbedtls_free( session_data );

View file

@ -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 );
rng_init( &rng );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init( &cacert );
mbedtls_x509_crt_init( &srvcert );
@ -1413,7 +1412,10 @@ int main( int argc, char *argv[] )
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
goto exit;
}
#endif
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
mbedtls_test_enable_insecure_external_rng( );
#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if !defined(_WIN32)
/* Abort cleanly on SIGTERM and SIGINT */
@ -2293,31 +2295,8 @@ int main( int argc, char *argv[] )
mbedtls_printf( "\n . Seeding the random number generator..." );
fflush( stdout );
mbedtls_entropy_init( &entropy );
if (opt.reproducible)
{
srand( 1 );
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, dummy_entropy,
&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( &ctr_drbg, mbedtls_entropy_func,
&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, opt.reproducible, pers ) != 0 )
goto exit;
mbedtls_printf( " ok\n" );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -2706,7 +2685,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, rng_get, &rng );
mbedtls_ssl_conf_dbg( &conf, my_debug, stdout );
#if defined(MBEDTLS_SSL_CACHE_C)
@ -2725,7 +2704,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,
rng_get, &rng,
MBEDTLS_CIPHER_AES_256_GCM,
opt.ticket_timeout ) ) != 0 )
{
@ -2747,7 +2726,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 )
rng_get, &rng ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret );
goto exit;
@ -2899,8 +2878,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 = &ctr_drbg;
ssl_async_keys.f_rng = rng_get;
ssl_async_keys.p_rng = &rng;
mbedtls_ssl_conf_async_private_cb( &conf,
sign,
decrypt,
@ -3998,8 +3977,7 @@ exit:
mbedtls_ssl_free( &ssl );
mbedtls_ssl_config_free( &conf );
mbedtls_ctr_drbg_free( &ctr_drbg );
mbedtls_entropy_free( &entropy );
rng_free( &rng );
#if defined(MBEDTLS_SSL_CACHE_C)
mbedtls_ssl_cache_free( &cache );

View file

@ -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;
@ -61,6 +61,84 @@ int dummy_entropy( void *data, unsigned char *output, size_t len )
return( ret );
}
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 );
}
int rng_seed( rng_context_t *rng, int reproducible, const char *pers )
{
int ( *f_entropy )( void *, unsigned char *, size_t ) =
( reproducible ? dummy_entropy : mbedtls_entropy_func );
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",
(unsigned int) -ret );
return( ret );
}
return( 0 );
}
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)
int ca_callback( void *data, mbedtls_x509_crt const *child,
mbedtls_x509_crt **candidates )

View file

@ -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"
@ -126,7 +130,72 @@ 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
{
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.
*
* 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 );
/** Generate random data.
*
* This function is suitable for use as the \c f_rng argument to Mbed TLS
* library functions.
*
* \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.
*
* \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_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 <test/fake_external_rng_for_test.h>
#endif
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
int ca_callback( void *data, mbedtls_x509_crt const *child,