From 0a4fb095342d07990b823e91ac39dd616bc86af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 7 May 2015 12:50:31 +0100 Subject: [PATCH] Make xxx_drbg_random() thread-safe --- ChangeLog | 4 ++++ include/mbedtls/ctr_drbg.h | 8 ++++++++ include/mbedtls/hmac_drbg.h | 8 ++++++++ library/ctr_drbg.c | 30 +++++++++++++++++++++++++++++- library/hmac_drbg.c | 31 +++++++++++++++++++++++++++++-- 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0b3735c42..4011512a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -94,6 +94,10 @@ Changes from the 1.4 preview branch * ssl_set_bio_timeout() was removed, split into mbedtls_ssl_set_bio() with 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 Security diff --git a/include/mbedtls/ctr_drbg.h b/include/mbedtls/ctr_drbg.h index 3ea4af2ec..cebf43b09 100644 --- a/include/mbedtls/ctr_drbg.h +++ b/include/mbedtls/ctr_drbg.h @@ -26,6 +26,10 @@ #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_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). */ @@ -99,6 +103,10 @@ typedef struct int (*f_entropy)(void *, unsigned char *, size_t); void *p_entropy; /*!< context for the entropy function */ + +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t mutex; +#endif } mbedtls_ctr_drbg_context; diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index fb2ee0eb1..eeac3e320 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -26,6 +26,10 @@ #include "md.h" +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + /* * Error codes */ @@ -87,6 +91,10 @@ typedef struct /* Callbacks */ int (*f_entropy)(void *, unsigned char *, size_t); /*!< 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; /** diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index ec7d9a773..54feb71c9 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -61,6 +61,10 @@ static void mbedtls_zeroize( void *v, size_t n ) { void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) { 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 ) return; +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif mbedtls_aes_free( &ctx->aes_ctx ); 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 ) { - 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) @@ -537,6 +559,8 @@ int mbedtls_ctr_drbg_self_test( int verbose ) CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); + mbedtls_ctr_drbg_free( &ctx ); + if( verbose != 0 ) mbedtls_printf( "passed\n" ); @@ -546,6 +570,8 @@ int mbedtls_ctr_drbg_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); + mbedtls_ctr_drbg_init( &ctx ); + test_offset = 0; CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, (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( memcmp( buf, result_nopr, 16 ) ); + mbedtls_ctr_drbg_free( &ctx ); + if( verbose != 0 ) mbedtls_printf( "passed\n" ); diff --git a/library/hmac_drbg.c b/library/hmac_drbg.c index 710eb8420..02fcc7d00 100644 --- a/library/hmac_drbg.c +++ b/library/hmac_drbg.c @@ -62,6 +62,10 @@ static void mbedtls_zeroize( void *v, size_t n ) { void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) { 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 ) { - 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 ) return; +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif mbedtls_md_free( &ctx->md_ctx ); - 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 ) ); mbedtls_hmac_drbg_free( &ctx ); + mbedtls_hmac_drbg_free( &ctx ); + if( verbose != 0 ) mbedtls_printf( "passed\n" ); @@ -490,6 +513,8 @@ int mbedtls_hmac_drbg_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( " HMAC_DRBG (PR = False) : " ); + mbedtls_hmac_drbg_init( &ctx ); + test_offset = 0; CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, 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 ) ); mbedtls_hmac_drbg_free( &ctx ); + mbedtls_hmac_drbg_free( &ctx ); + if( verbose != 0 ) mbedtls_printf( "passed\n" );