Make xxx_drbg_random() thread-safe

This commit is contained in:
Manuel Pégourié-Gonnard 2015-05-07 12:50:31 +01:00
parent 750e4d7769
commit 0a4fb09534
5 changed files with 78 additions and 3 deletions

View File

@ -94,6 +94,10 @@ Changes from the 1.4 preview branch
* ssl_set_bio_timeout() was removed, split into mbedtls_ssl_set_bio() with * ssl_set_bio_timeout() was removed, split into mbedtls_ssl_set_bio() with
new prototype, and mbedtls_ssl_set_read_timeout(). new prototype, and mbedtls_ssl_set_read_timeout().
Changes
* mbedtls_ctr_drbg_random() and mbedtls_hmac_drbg_random() are now
thread-safe if MBEDTLS_THREADING_C is enabled.
= mbed TLS 1.3 branch = mbed TLS 1.3 branch
Security Security

View File

@ -26,6 +26,10 @@
#include "aes.h" #include "aes.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
#define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */ #define MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */
#define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */ #define MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */
@ -99,6 +103,10 @@ typedef struct
int (*f_entropy)(void *, unsigned char *, size_t); int (*f_entropy)(void *, unsigned char *, size_t);
void *p_entropy; /*!< context for the entropy function */ void *p_entropy; /*!< context for the entropy function */
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
} }
mbedtls_ctr_drbg_context; mbedtls_ctr_drbg_context;

View File

@ -26,6 +26,10 @@
#include "md.h" #include "md.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
/* /*
* Error codes * Error codes
*/ */
@ -87,6 +91,10 @@ typedef struct
/* Callbacks */ /* Callbacks */
int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */
void *p_entropy; /*!< context for the entropy function */ void *p_entropy; /*!< context for the entropy function */
#if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex;
#endif
} mbedtls_hmac_drbg_context; } mbedtls_hmac_drbg_context;
/** /**

View File

@ -61,6 +61,10 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
} }
/* /*
@ -115,6 +119,9 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
#endif
mbedtls_aes_free( &ctx->aes_ctx ); mbedtls_aes_free( &ctx->aes_ctx );
mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
} }
@ -392,7 +399,22 @@ 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 ) int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
{ {
return mbedtls_ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 ); int ret;
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
} }
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
@ -537,6 +559,8 @@ int mbedtls_ctr_drbg_self_test( int verbose )
CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
mbedtls_ctr_drbg_free( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -546,6 +570,8 @@ int mbedtls_ctr_drbg_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
mbedtls_ctr_drbg_init( &ctx );
test_offset = 0; test_offset = 0;
CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
@ -554,6 +580,8 @@ int mbedtls_ctr_drbg_self_test( int verbose )
CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
CHK( memcmp( buf, result_nopr, 16 ) ); CHK( memcmp( buf, result_nopr, 16 ) );
mbedtls_ctr_drbg_free( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );

View File

@ -62,6 +62,10 @@ static void mbedtls_zeroize( void *v, size_t n ) {
void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_init( &ctx->mutex );
#endif
} }
/* /*
@ -313,7 +317,22 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
*/ */
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
{ {
return( mbedtls_hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) ); int ret;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret );
#endif
ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif
return( ret );
} }
/* /*
@ -324,8 +343,10 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; return;
#if defined(MBEDTLS_THREADING_C)
mbedtls_mutex_free( &ctx->mutex );
#endif
mbedtls_md_free( &ctx->md_ctx ); mbedtls_md_free( &ctx->md_ctx );
mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
} }
@ -481,6 +502,8 @@ int mbedtls_hmac_drbg_self_test( int verbose )
CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
mbedtls_hmac_drbg_free( &ctx ); mbedtls_hmac_drbg_free( &ctx );
mbedtls_hmac_drbg_free( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
@ -490,6 +513,8 @@ int mbedtls_hmac_drbg_self_test( int verbose )
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " HMAC_DRBG (PR = False) : " ); mbedtls_printf( " HMAC_DRBG (PR = False) : " );
mbedtls_hmac_drbg_init( &ctx );
test_offset = 0; test_offset = 0;
CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
hmac_drbg_self_test_entropy, (void *) entropy_nopr, hmac_drbg_self_test_entropy, (void *) entropy_nopr,
@ -500,6 +525,8 @@ int mbedtls_hmac_drbg_self_test( int verbose )
CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
mbedtls_hmac_drbg_free( &ctx ); mbedtls_hmac_drbg_free( &ctx );
mbedtls_hmac_drbg_free( &ctx );
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );