Merge pull request #4104 from gilles-peskine-arm/test-mutex-usage-count-development
Test and fix mutex usage
This commit is contained in:
commit
a0fd0f8531
5
ChangeLog.d/drbg-mutex.txt
Normal file
5
ChangeLog.d/drbg-mutex.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Bugfix
|
||||
* Fix a resource leak in CTR_DRBG and HMAC_DRBG when MBEDTLS_THREADING_C
|
||||
is enabled, on platforms where initializing a mutex allocates resources.
|
||||
This was a regression introduced in the previous release. Reported in
|
||||
#4017, #4045 and #4071.
|
13
ChangeLog.d/rsa-mutex.txt
Normal file
13
ChangeLog.d/rsa-mutex.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Bugfix
|
||||
* Ensure that calling mbedtls_rsa_free() or mbedtls_entropy_free()
|
||||
twice is safe. This happens for RSA when some Mbed TLS library functions
|
||||
fail. Such a double-free was not safe when MBEDTLS_THREADING_C was
|
||||
enabled on platforms where freeing a mutex twice is not safe.
|
||||
* Fix a resource leak in a bad-arguments case of mbedtls_rsa_gen_key()
|
||||
when MBEDTLS_THREADING_C is enabled on platforms where initializing
|
||||
a mutex allocates resources.
|
||||
|
||||
Default behavior changes
|
||||
* In mbedtls_rsa_context objects, the ver field was formerly documented
|
||||
as always 0. It is now reserved for internal purposes and may take
|
||||
different values.
|
@ -200,6 +200,13 @@ typedef struct mbedtls_ctr_drbg_context
|
||||
void *p_entropy; /*!< The context for the entropy function. */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Invariant: the mutex is initialized if and only if f_entropy != NULL.
|
||||
* This means that the mutex is initialized during the initial seeding
|
||||
* in mbedtls_ctr_drbg_seed() and freed in mbedtls_ctr_drbg_free().
|
||||
*
|
||||
* Note that this invariant may change without notice. Do not rely on it
|
||||
* and do not access the mutex directly in application code.
|
||||
*/
|
||||
mbedtls_threading_mutex_t mutex;
|
||||
#endif
|
||||
}
|
||||
@ -264,6 +271,15 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
|
||||
* make a second call to \p f_entropy.
|
||||
*/
|
||||
#endif
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* after this function returns successfully,
|
||||
* it is safe to call mbedtls_ctr_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* - The \p custom string.
|
||||
*
|
||||
@ -290,6 +306,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
|
||||
* the same context unless you call
|
||||
* mbedtls_ctr_drbg_free() and mbedtls_ctr_drbg_init()
|
||||
* again first.
|
||||
* After a failed call to mbedtls_ctr_drbg_seed(),
|
||||
* you must call mbedtls_ctr_drbg_free().
|
||||
* \param f_entropy The entropy callback, taking as arguments the
|
||||
* \p p_entropy context, the buffer to fill, and the
|
||||
* length of the buffer.
|
||||
@ -405,6 +423,11 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
|
||||
* \brief This function reseeds the CTR_DRBG context, that is
|
||||
* extracts data from the entropy source.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param additional Additional data to add to the state. Can be \c NULL.
|
||||
* \param len The length of the additional data.
|
||||
@ -422,6 +445,11 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
|
||||
/**
|
||||
* \brief This function updates the state of the CTR_DRBG context.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The CTR_DRBG context.
|
||||
* \param additional The data to update the state with. This must not be
|
||||
* \c NULL unless \p add_len is \c 0.
|
||||
@ -445,6 +473,11 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param p_rng The CTR_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_ctr_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
@ -473,8 +506,16 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
|
||||
*
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* it is safe to call mbedtls_ctr_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param p_rng The CTR_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_ctr_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
|
@ -120,13 +120,15 @@ mbedtls_entropy_source_state;
|
||||
*/
|
||||
typedef struct mbedtls_entropy_context
|
||||
{
|
||||
int accumulator_started;
|
||||
int accumulator_started; /* 0 after init.
|
||||
* 1 after the first update.
|
||||
* -1 after free. */
|
||||
#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
|
||||
mbedtls_sha512_context accumulator;
|
||||
#else
|
||||
mbedtls_sha256_context accumulator;
|
||||
#endif
|
||||
int source_count;
|
||||
int source_count; /* Number of entries used in source. */
|
||||
mbedtls_entropy_source_state source[MBEDTLS_ENTROPY_MAX_SOURCES];
|
||||
#if defined(MBEDTLS_HAVEGE_C)
|
||||
mbedtls_havege_state havege_data;
|
||||
|
@ -101,6 +101,14 @@ typedef struct mbedtls_hmac_drbg_context
|
||||
void *p_entropy; /*!< context for the entropy function */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Invariant: the mutex is initialized if and only if
|
||||
* md_ctx->md_info != NULL. This means that the mutex is initialized
|
||||
* during the initial seeding in mbedtls_hmac_drbg_seed() or
|
||||
* mbedtls_hmac_drbg_seed_buf() and freed in mbedtls_ctr_drbg_free().
|
||||
*
|
||||
* Note that this invariant may change without notice. Do not rely on it
|
||||
* and do not access the mutex directly in application code.
|
||||
*/
|
||||
mbedtls_threading_mutex_t mutex;
|
||||
#endif
|
||||
} mbedtls_hmac_drbg_context;
|
||||
@ -150,7 +158,17 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx );
|
||||
* \note During the initial seeding, this function calls
|
||||
* the entropy source to obtain a nonce
|
||||
* whose length is half the entropy length.
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* after this function returns successfully,
|
||||
* it is safe to call mbedtls_hmac_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param ctx HMAC_DRBG context to be seeded.
|
||||
* \param md_info MD algorithm to use for HMAC_DRBG.
|
||||
* \param f_entropy The entropy callback, taking as arguments the
|
||||
@ -189,7 +207,17 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
||||
*
|
||||
* This function is meant for use in algorithms that need a pseudorandom
|
||||
* input such as deterministic ECDSA.
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* after this function returns successfully,
|
||||
* it is safe to call mbedtls_hmac_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param ctx HMAC_DRBG context to be initialised.
|
||||
* \param md_info MD algorithm to use for HMAC_DRBG.
|
||||
* \param data Concatenation of the initial entropy string and
|
||||
@ -252,6 +280,11 @@ void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx,
|
||||
/**
|
||||
* \brief This function updates the state of the HMAC_DRBG context.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param additional The data to update the state with.
|
||||
* If this is \c NULL, there is no additional data.
|
||||
@ -268,6 +301,11 @@ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
|
||||
* \brief This function reseeds the HMAC_DRBG context, that is
|
||||
* extracts data from the entropy source.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param ctx The HMAC_DRBG context.
|
||||
* \param additional Additional data to add to the state.
|
||||
* If this is \c NULL, there is no additional data
|
||||
@ -293,6 +331,11 @@ int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*
|
||||
* \note This function is not thread-safe. It is not safe
|
||||
* to call this function if another thread might be
|
||||
* concurrently obtaining random numbers from the same
|
||||
* context or updating or reseeding the same context.
|
||||
*
|
||||
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_hmac_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
@ -322,7 +365,16 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
|
||||
*
|
||||
* This function automatically reseeds if the reseed counter is exceeded
|
||||
* or prediction resistance is enabled.
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/**
|
||||
* \note When Mbed TLS is built with threading support,
|
||||
* it is safe to call mbedtls_ctr_drbg_random()
|
||||
* from multiple threads. Other operations, including
|
||||
* reseeding, are not thread-safe.
|
||||
*/
|
||||
#endif /* MBEDTLS_THREADING_C */
|
||||
/**
|
||||
* \param p_rng The HMAC_DRBG context. This must be a pointer to a
|
||||
* #mbedtls_hmac_drbg_context structure.
|
||||
* \param output The buffer to fill.
|
||||
|
@ -97,7 +97,10 @@ extern "C" {
|
||||
*/
|
||||
typedef struct mbedtls_rsa_context
|
||||
{
|
||||
int ver; /*!< Always 0.*/
|
||||
int ver; /*!< Reserved for internal purposes.
|
||||
* Do not set this field in application
|
||||
* code. Its meaning might change without
|
||||
* notice. */
|
||||
size_t len; /*!< The size of \p N in Bytes. */
|
||||
|
||||
mbedtls_mpi N; /*!< The public modulus. */
|
||||
@ -127,6 +130,7 @@ typedef struct mbedtls_rsa_context
|
||||
mask generating function used in the
|
||||
EME-OAEP and EMSA-PSS encodings. */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Invariant: the mutex is initialized iff ver != 0. */
|
||||
mbedtls_threading_mutex_t mutex; /*!< Thread-safety mutex. */
|
||||
#endif
|
||||
}
|
||||
|
@ -46,6 +46,9 @@ extern "C" {
|
||||
typedef struct mbedtls_threading_mutex_t
|
||||
{
|
||||
pthread_mutex_t mutex;
|
||||
/* is_valid is 0 after a failed init or a free, and nonzero after a
|
||||
* successful init. This field is not considered part of the public
|
||||
* API of Mbed TLS and may change without notice. */
|
||||
char is_valid;
|
||||
} mbedtls_threading_mutex_t;
|
||||
#endif
|
||||
|
@ -56,10 +56,6 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
|
||||
ctx->reseed_counter = -1;
|
||||
|
||||
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -72,15 +68,14 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
|
||||
return;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
/* The mutex is initialized iff f_entropy is set. */
|
||||
if( ctx->f_entropy != NULL )
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
#endif
|
||||
mbedtls_aes_free( &ctx->aes_ctx );
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
|
||||
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
|
||||
ctx->reseed_counter = -1;
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
}
|
||||
|
||||
void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
|
||||
@ -464,6 +459,11 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
|
||||
|
||||
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
|
||||
|
||||
/* The mutex is initialized iff f_entropy is set. */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
|
||||
mbedtls_aes_init( &ctx->aes_ctx );
|
||||
|
||||
ctx->f_entropy = f_entropy;
|
||||
|
@ -116,6 +116,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
|
||||
|
||||
void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
|
||||
{
|
||||
/* If the context was already free, don't call free() again.
|
||||
* This is important for mutexes which don't allow double-free. */
|
||||
if( ctx->accumulator_started == -1 )
|
||||
return;
|
||||
|
||||
#if defined(MBEDTLS_HAVEGE_C)
|
||||
mbedtls_havege_free( &ctx->havege_data );
|
||||
#endif
|
||||
@ -132,7 +137,7 @@ void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
|
||||
#endif
|
||||
ctx->source_count = 0;
|
||||
mbedtls_platform_zeroize( ctx->source, sizeof( ctx->source ) );
|
||||
ctx->accumulator_started = 0;
|
||||
ctx->accumulator_started = -1;
|
||||
}
|
||||
|
||||
int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
|
||||
|
@ -54,10 +54,6 @@ void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
|
||||
memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
|
||||
|
||||
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,6 +125,10 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
|
||||
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set initial working state.
|
||||
* Use the V memory location, which is currently all 0, to initialize the
|
||||
@ -254,6 +254,11 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
|
||||
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
|
||||
return( ret );
|
||||
|
||||
/* The mutex is initialized iff the md context is set up. */
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
|
||||
md_size = mbedtls_md_get_size( md_info );
|
||||
|
||||
/*
|
||||
@ -421,14 +426,13 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
|
||||
return;
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
/* The mutex is initialized iff the md context is set up. */
|
||||
if( ctx->md_ctx.md_info != NULL )
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
#endif
|
||||
mbedtls_md_free( &ctx->md_ctx );
|
||||
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
|
||||
ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_FS_IO)
|
||||
|
@ -490,6 +490,9 @@ void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
|
||||
mbedtls_rsa_set_padding( ctx, padding, hash_id );
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
/* Set ctx->ver to nonzero to indicate that the mutex has been
|
||||
* initialized and will need to be freed. */
|
||||
ctx->ver = 1;
|
||||
mbedtls_mutex_init( &ctx->mutex );
|
||||
#endif
|
||||
}
|
||||
@ -537,9 +540,6 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
||||
RSA_VALIDATE_RET( ctx != NULL );
|
||||
RSA_VALIDATE_RET( f_rng != NULL );
|
||||
|
||||
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
|
||||
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
/*
|
||||
* If the modulus is 1024 bit long or shorter, then the security strength of
|
||||
* the RSA algorithm is less than or equal to 80 bits and therefore an error
|
||||
@ -552,6 +552,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
|
||||
mbedtls_mpi_init( &G );
|
||||
mbedtls_mpi_init( &L );
|
||||
|
||||
if( nbits < 128 || exponent < 3 || nbits % 2 != 0 )
|
||||
{
|
||||
ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* find primes P and Q with Q < P so that:
|
||||
* 1. |P-Q| > 2^( nbits / 2 - 100 )
|
||||
@ -629,7 +635,9 @@ cleanup:
|
||||
if( ret != 0 )
|
||||
{
|
||||
mbedtls_rsa_free( ctx );
|
||||
return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret );
|
||||
if( ( -ret & ~0x7f ) == 0 )
|
||||
ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
@ -2481,7 +2489,6 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
|
||||
RSA_VALIDATE_RET( dst != NULL );
|
||||
RSA_VALIDATE_RET( src != NULL );
|
||||
|
||||
dst->ver = src->ver;
|
||||
dst->len = src->len;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
|
||||
@ -2540,7 +2547,12 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
|
||||
#endif /* MBEDTLS_RSA_NO_CRT */
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C)
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
/* Free the mutex, but only if it hasn't been freed already. */
|
||||
if( ctx->ver != 0 )
|
||||
{
|
||||
mbedtls_mutex_free( &ctx->mutex );
|
||||
ctx->ver = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,12 @@ static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
|
||||
if( mutex == NULL )
|
||||
return;
|
||||
|
||||
/* A nonzero value of is_valid indicates a successfully initialized
|
||||
* mutex. This is a workaround for not being able to return an error
|
||||
* code for this function. The lock/unlock functions return an error
|
||||
* if is_valid is nonzero. The Mbed TLS unit test code uses this field
|
||||
* to distinguish more states of the mutex; see
|
||||
* tests/src/threading_helpers for details. */
|
||||
mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
|
||||
}
|
||||
|
||||
|
@ -734,6 +734,10 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
test_hooks_init( );
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
/*
|
||||
* Make sure memory references are valid.
|
||||
*/
|
||||
@ -3036,6 +3040,20 @@ exit:
|
||||
mbedtls_free( context_buf );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free( );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
if( test_hooks_failure_detected( ) )
|
||||
{
|
||||
if( ret == 0 )
|
||||
ret = 1;
|
||||
mbedtls_printf( "Test hooks detected errors.\n" );
|
||||
}
|
||||
test_hooks_free( );
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
|
||||
#if defined(MBEDTLS_MEMORY_DEBUG)
|
||||
mbedtls_memory_buffer_alloc_status();
|
||||
|
@ -1369,6 +1369,10 @@ int main( int argc, char *argv[] )
|
||||
#endif /* MBEDTLS_MEMORY_DEBUG */
|
||||
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
test_hooks_init( );
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
/*
|
||||
* Make sure memory references are valid in case we exit early.
|
||||
*/
|
||||
@ -3998,6 +4002,26 @@ exit:
|
||||
mbedtls_free( context_buf );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
mbedtls_psa_crypto_free( );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
/* Let test hooks detect errors such as resource leaks.
|
||||
* Don't do it in query_config mode, because some test code prints
|
||||
* information to stdout and this gets mixed with the regular output. */
|
||||
if( opt.query_config_mode == DFL_QUERY_CONFIG_MODE )
|
||||
{
|
||||
if( test_hooks_failure_detected( ) )
|
||||
{
|
||||
if( ret == 0 )
|
||||
ret = 1;
|
||||
mbedtls_printf( "Test hooks detected errors.\n" );
|
||||
}
|
||||
}
|
||||
test_hooks_free( );
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
|
||||
#if defined(MBEDTLS_MEMORY_DEBUG)
|
||||
mbedtls_memory_buffer_alloc_status();
|
||||
|
@ -22,6 +22,10 @@
|
||||
|
||||
#include "ssl_test_lib.h"
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
#include "test/helpers.h"
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
|
||||
|
||||
void my_debug( void *ctx, int level,
|
||||
@ -321,4 +325,33 @@ int idle( mbedtls_net_context *fd,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
|
||||
void test_hooks_init( void )
|
||||
{
|
||||
mbedtls_test_info_reset( );
|
||||
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
mbedtls_test_mutex_usage_init( );
|
||||
#endif
|
||||
}
|
||||
|
||||
int test_hooks_failure_detected( void )
|
||||
{
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
/* Errors are reported via mbedtls_test_info. */
|
||||
mbedtls_test_mutex_usage_check( );
|
||||
#endif
|
||||
|
||||
if( mbedtls_test_info.result != MBEDTLS_TEST_RESULT_SUCCESS )
|
||||
return( 1 );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void test_hooks_free( void )
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#endif /* !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) */
|
||||
|
@ -258,5 +258,37 @@ int idle( mbedtls_net_context *fd,
|
||||
#endif
|
||||
int idle_reason );
|
||||
|
||||
#if defined(MBEDTLS_TEST_HOOKS)
|
||||
/** Initialize whatever test hooks are enabled by the compile-time
|
||||
* configuration and make sense for the TLS test programs. */
|
||||
void test_hooks_init( void );
|
||||
|
||||
/** Check if any test hooks detected a problem.
|
||||
*
|
||||
* If a problem was detected, it's ok for the calling program to keep going,
|
||||
* but it should ultimately exit with an error status.
|
||||
*
|
||||
* \note When implementing a test hook that detects errors on its own
|
||||
* (as opposed to e.g. leaving the error for a memory sanitizer to
|
||||
* report), make sure to print a message to standard error either at
|
||||
* the time the problem is detected or during the execution of this
|
||||
* function. This function does not indicate what problem was detected,
|
||||
* so printing a message is the only way to provide feedback in the
|
||||
* logs of the calling program.
|
||||
*
|
||||
* \return Nonzero if a problem was detected.
|
||||
* \c 0 if no problem was detected.
|
||||
*/
|
||||
int test_hooks_failure_detected( void );
|
||||
|
||||
/** Free any resources allocated for the sake of test hooks.
|
||||
*
|
||||
* Call this at the end of the program so that resource leak analyzers
|
||||
* don't complain.
|
||||
*/
|
||||
void test_hooks_free( void );
|
||||
|
||||
#endif /* !MBEDTLS_TEST_HOOKS */
|
||||
|
||||
#endif /* MBEDTLS_SSL_TEST_IMPOSSIBLE conditions: else */
|
||||
#endif /* MBEDTLS_PROGRAMS_SSL_SSL_TEST_LIB_H */
|
||||
|
@ -31,6 +31,11 @@
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
|
||||
defined(MBEDTLS_TEST_HOOKS)
|
||||
#define MBEDTLS_TEST_MUTEX_USAGE
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PLATFORM_C)
|
||||
#include "mbedtls/platform.h"
|
||||
#else
|
||||
@ -63,6 +68,9 @@ typedef struct
|
||||
const char *filename;
|
||||
int line_no;
|
||||
unsigned long step;
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
const char *mutex_usage_error;
|
||||
#endif
|
||||
}
|
||||
mbedtls_test_info_t;
|
||||
extern mbedtls_test_info_t mbedtls_test_info;
|
||||
@ -260,4 +268,14 @@ void mbedtls_test_param_failed_reset_state( void );
|
||||
#include "test/fake_external_rng_for_test.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
/** Permanently activate the mutex usage verification framework. See
|
||||
* threading_helpers.c for information. */
|
||||
void mbedtls_test_mutex_usage_init( void );
|
||||
|
||||
/** Call this function after executing a test case to check for mutex usage
|
||||
* errors. */
|
||||
void mbedtls_test_mutex_usage_check( void );
|
||||
#endif /* MBEDTLS_TEST_MUTEX_USAGE */
|
||||
|
||||
#endif /* TEST_HELPERS_H */
|
||||
|
@ -22,11 +22,20 @@
|
||||
#define PSA_CRYPTO_HELPERS_H
|
||||
|
||||
#include "test/helpers.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
|
||||
#include "test/psa_helpers.h"
|
||||
|
||||
#include <psa/crypto.h>
|
||||
#include <psa_crypto_slot_management.h>
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "mbedtls/psa_util.h"
|
||||
#endif
|
||||
|
||||
#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
|
||||
|
||||
/** Check for things that have not been cleaned up properly in the
|
||||
* PSA subsystem.
|
||||
*
|
||||
@ -185,4 +194,29 @@ psa_status_t mbedtls_test_record_status( psa_status_t status,
|
||||
} \
|
||||
while( 0 )
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
/** \def USE_PSA_INIT
|
||||
*
|
||||
* Call this macro to initialize the PSA subsystem if #MBEDTLS_USE_PSA_CRYPTO
|
||||
* is enabled and do nothing otherwise. If the initialization fails, mark
|
||||
* the test case as failed and jump to the \p exit label.
|
||||
*/
|
||||
/** \def USE_PSA_DONE
|
||||
*
|
||||
* Call this macro at the end of a test case if you called #USE_PSA_INIT.
|
||||
* This is like #PSA_DONE, except that it does nothing if
|
||||
* #MBEDTLS_USE_PSA_CRYPTO is disabled.
|
||||
*/
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#define USE_PSA_INIT( ) PSA_INIT( )
|
||||
#define USE_PSA_DONE( ) PSA_DONE( )
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
/* Define empty macros so that we can use them in the preamble and teardown
|
||||
* of every test function that uses PSA conditionally based on
|
||||
* MBEDTLS_USE_PSA_CRYPTO. */
|
||||
#define USE_PSA_INIT( ) ( (void) 0 )
|
||||
#define USE_PSA_DONE( ) ( (void) 0 )
|
||||
#endif /* !MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#endif /* PSA_CRYPTO_HELPERS_H */
|
||||
|
223
tests/src/threading_helpers.c
Normal file
223
tests/src/threading_helpers.c
Normal file
@ -0,0 +1,223 @@
|
||||
/** Mutex usage verification framework. */
|
||||
|
||||
/*
|
||||
* 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 <test/helpers.h>
|
||||
#include <test/macros.h>
|
||||
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
|
||||
#include "mbedtls/threading.h"
|
||||
|
||||
/** Mutex usage verification framework.
|
||||
*
|
||||
* The mutex usage verification code below aims to detect bad usage of
|
||||
* Mbed TLS's mutex abstraction layer at runtime. Note that this is solely
|
||||
* about the use of the mutex itself, not about checking whether the mutex
|
||||
* correctly protects whatever it is supposed to protect.
|
||||
*
|
||||
* The normal usage of a mutex is:
|
||||
* ```
|
||||
* digraph mutex_states {
|
||||
* "UNINITIALIZED"; // the initial state
|
||||
* "IDLE";
|
||||
* "FREED";
|
||||
* "LOCKED";
|
||||
* "UNINITIALIZED" -> "IDLE" [label="init"];
|
||||
* "FREED" -> "IDLE" [label="init"];
|
||||
* "IDLE" -> "LOCKED" [label="lock"];
|
||||
* "LOCKED" -> "IDLE" [label="unlock"];
|
||||
* "IDLE" -> "FREED" [label="free"];
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* All bad transitions that can be unambiguously detected are reported.
|
||||
* An attempt to use an uninitialized mutex cannot be detected in general
|
||||
* since the memory content may happen to denote a valid state. For the same
|
||||
* reason, a double init cannot be detected.
|
||||
* All-bits-zero is the state of a freed mutex, which is distinct from an
|
||||
* initialized mutex, so attempting to use zero-initialized memory as a mutex
|
||||
* without calling the init function is detected.
|
||||
*
|
||||
* The framework attempts to detect missing calls to init and free by counting
|
||||
* calls to init and free. If there are more calls to init than free, this
|
||||
* means that a mutex is not being freed somewhere, which is a memory leak
|
||||
* on platforms where a mutex consumes resources other than the
|
||||
* mbedtls_threading_mutex_t object itself. If there are more calls to free
|
||||
* than init, this indicates a missing init, which is likely to be detected
|
||||
* by an attempt to lock the mutex as well. A limitation of this framework is
|
||||
* that it cannot detect scenarios where there is exactly the same number of
|
||||
* calls to init and free but the calls don't match. A bug like this is
|
||||
* unlikely to happen uniformly throughout the whole test suite though.
|
||||
*
|
||||
* If an error is detected, this framework will report what happened and the
|
||||
* test case will be marked as failed. Unfortunately, the error report cannot
|
||||
* indicate the exact location of the problematic call. To locate the error,
|
||||
* use a debugger and set a breakpoint on mbedtls_test_mutex_usage_error().
|
||||
*/
|
||||
enum value_of_mutex_is_valid_field
|
||||
{
|
||||
/* Potential values for the is_valid field of mbedtls_threading_mutex_t.
|
||||
* Note that MUTEX_FREED must be 0 and MUTEX_IDLE must be 1 for
|
||||
* compatibility with threading_mutex_init_pthread() and
|
||||
* threading_mutex_free_pthread(). MUTEX_LOCKED could be any nonzero
|
||||
* value. */
|
||||
MUTEX_FREED = 0, //!< Set by threading_mutex_free_pthread
|
||||
MUTEX_IDLE = 1, //!< Set by threading_mutex_init_pthread and by our unlock
|
||||
MUTEX_LOCKED = 2, //!< Set by our lock
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*init)( mbedtls_threading_mutex_t * );
|
||||
void (*free)( mbedtls_threading_mutex_t * );
|
||||
int (*lock)( mbedtls_threading_mutex_t * );
|
||||
int (*unlock)( mbedtls_threading_mutex_t * );
|
||||
} mutex_functions_t;
|
||||
static mutex_functions_t mutex_functions;
|
||||
|
||||
/** The total number of calls to mbedtls_mutex_init(), minus the total number
|
||||
* of calls to mbedtls_mutex_free().
|
||||
*
|
||||
* Reset to 0 after each test case.
|
||||
*/
|
||||
static int live_mutexes;
|
||||
|
||||
static void mbedtls_test_mutex_usage_error( mbedtls_threading_mutex_t *mutex,
|
||||
const char *msg )
|
||||
{
|
||||
(void) mutex;
|
||||
if( mbedtls_test_info.mutex_usage_error == NULL )
|
||||
mbedtls_test_info.mutex_usage_error = msg;
|
||||
mbedtls_fprintf( stdout, "[mutex: %s] ", msg );
|
||||
/* Don't mark the test as failed yet. This way, if the test fails later
|
||||
* for a functional reason, the test framework will report the message
|
||||
* and location for this functional reason. If the test passes,
|
||||
* mbedtls_test_mutex_usage_check() will mark it as failed. */
|
||||
}
|
||||
|
||||
static void mbedtls_test_wrap_mutex_init( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
mutex_functions.init( mutex );
|
||||
if( mutex->is_valid )
|
||||
++live_mutexes;
|
||||
}
|
||||
|
||||
static void mbedtls_test_wrap_mutex_free( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
switch( mutex->is_valid )
|
||||
{
|
||||
case MUTEX_FREED:
|
||||
mbedtls_test_mutex_usage_error( mutex, "free without init or double free" );
|
||||
break;
|
||||
case MUTEX_IDLE:
|
||||
/* Do nothing. The underlying free function will reset is_valid
|
||||
* to 0. */
|
||||
break;
|
||||
case MUTEX_LOCKED:
|
||||
mbedtls_test_mutex_usage_error( mutex, "free without unlock" );
|
||||
break;
|
||||
default:
|
||||
mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
|
||||
break;
|
||||
}
|
||||
if( mutex->is_valid )
|
||||
--live_mutexes;
|
||||
mutex_functions.free( mutex );
|
||||
}
|
||||
|
||||
static int mbedtls_test_wrap_mutex_lock( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
int ret = mutex_functions.lock( mutex );
|
||||
switch( mutex->is_valid )
|
||||
{
|
||||
case MUTEX_FREED:
|
||||
mbedtls_test_mutex_usage_error( mutex, "lock without init" );
|
||||
break;
|
||||
case MUTEX_IDLE:
|
||||
if( ret == 0 )
|
||||
mutex->is_valid = 2;
|
||||
break;
|
||||
case MUTEX_LOCKED:
|
||||
mbedtls_test_mutex_usage_error( mutex, "double lock" );
|
||||
break;
|
||||
default:
|
||||
mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
|
||||
break;
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int mbedtls_test_wrap_mutex_unlock( mbedtls_threading_mutex_t *mutex )
|
||||
{
|
||||
int ret = mutex_functions.unlock( mutex );
|
||||
switch( mutex->is_valid )
|
||||
{
|
||||
case MUTEX_FREED:
|
||||
mbedtls_test_mutex_usage_error( mutex, "unlock without init" );
|
||||
break;
|
||||
case MUTEX_IDLE:
|
||||
mbedtls_test_mutex_usage_error( mutex, "unlock without lock" );
|
||||
break;
|
||||
case MUTEX_LOCKED:
|
||||
if( ret == 0 )
|
||||
mutex->is_valid = MUTEX_IDLE;
|
||||
break;
|
||||
default:
|
||||
mbedtls_test_mutex_usage_error( mutex, "corrupted state" );
|
||||
break;
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
void mbedtls_test_mutex_usage_init( void )
|
||||
{
|
||||
mutex_functions.init = mbedtls_mutex_init;
|
||||
mutex_functions.free = mbedtls_mutex_free;
|
||||
mutex_functions.lock = mbedtls_mutex_lock;
|
||||
mutex_functions.unlock = mbedtls_mutex_unlock;
|
||||
mbedtls_mutex_init = &mbedtls_test_wrap_mutex_init;
|
||||
mbedtls_mutex_free = &mbedtls_test_wrap_mutex_free;
|
||||
mbedtls_mutex_lock = &mbedtls_test_wrap_mutex_lock;
|
||||
mbedtls_mutex_unlock = &mbedtls_test_wrap_mutex_unlock;
|
||||
}
|
||||
|
||||
void mbedtls_test_mutex_usage_check( void )
|
||||
{
|
||||
if( live_mutexes != 0 )
|
||||
{
|
||||
/* A positive number (more init than free) means that a mutex resource
|
||||
* is leaking (on platforms where a mutex consumes more than the
|
||||
* mbedtls_threading_mutex_t object itself). The rare case of a
|
||||
* negative number means a missing init somewhere. */
|
||||
mbedtls_fprintf( stdout, "[mutex: %d leaked] ", live_mutexes );
|
||||
live_mutexes = 0;
|
||||
if( mbedtls_test_info.mutex_usage_error == NULL )
|
||||
mbedtls_test_info.mutex_usage_error = "missing free";
|
||||
}
|
||||
if( mbedtls_test_info.mutex_usage_error != NULL &&
|
||||
mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED )
|
||||
{
|
||||
/* Functionally, the test passed. But there was a mutex usage error,
|
||||
* so mark the test as failed after all. */
|
||||
mbedtls_test_fail( "Mutex usage error", __LINE__, __FILE__ );
|
||||
}
|
||||
mbedtls_test_info.mutex_usage_error = NULL;
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_TEST_MUTEX_USAGE */
|
@ -5,9 +5,7 @@
|
||||
#include <test/macros.h>
|
||||
#include <test/helpers.h>
|
||||
#include <test/random.h>
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#include <test/psa_crypto_helpers.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -536,6 +536,10 @@ int execute_tests( int argc , const char ** argv )
|
||||
mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
mbedtls_test_mutex_usage_init( );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The C standard doesn't guarantee that all-bits-0 is the representation
|
||||
* of a NULL pointer. We do however use that in our code for initializing
|
||||
|
@ -188,6 +188,10 @@ void execute_function_ptr(TestWrapper_t fp, void **params)
|
||||
#else
|
||||
fp( params );
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
|
||||
mbedtls_test_mutex_usage_check( );
|
||||
#endif /* MBEDTLS_TEST_MUTEX_USAGE */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,3 +1,9 @@
|
||||
Entropy init-free-free
|
||||
entropy_init_free:0
|
||||
|
||||
Entropy init-free-init-free
|
||||
entropy_init_free:1
|
||||
|
||||
Create NV seed_file
|
||||
nv_seed_file_create:
|
||||
|
||||
|
@ -134,6 +134,28 @@ int read_nv_seed( unsigned char *buf, size_t buf_len )
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void entropy_init_free( int reinit )
|
||||
{
|
||||
mbedtls_entropy_context ctx;
|
||||
|
||||
/* Double free is not explicitly documented to work, but it is convenient
|
||||
* to call mbedtls_entropy_free() unconditionally on an error path without
|
||||
* checking whether it has already been called in the success path. */
|
||||
|
||||
mbedtls_entropy_init( &ctx );
|
||||
mbedtls_entropy_free( &ctx );
|
||||
|
||||
if( reinit )
|
||||
mbedtls_entropy_init( &ctx );
|
||||
mbedtls_entropy_free( &ctx );
|
||||
|
||||
/* This test case always succeeds, functionally speaking. A plausible
|
||||
* bug might trigger an invalid pointer dereference or a memory leak. */
|
||||
goto exit;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
|
||||
void entropy_seed_file( char * path, int ret )
|
||||
{
|
||||
@ -217,6 +239,9 @@ void entropy_func_len( int len, int ret )
|
||||
|
||||
for( j = len; j < sizeof( buf ); j++ )
|
||||
TEST_ASSERT( acc[j] == 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_entropy_free( &ctx );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -15,18 +15,6 @@
|
||||
* unconditionally (https://github.com/ARMmbed/mbedtls/issues/2023). */
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "mbedtls/psa_util.h"
|
||||
#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
|
||||
#else
|
||||
/* Define empty macros so that we can use them in the preamble and teardown
|
||||
* of every test function that uses PSA conditionally based on
|
||||
* MBEDTLS_USE_PSA_CRYPTO. */
|
||||
#define PSA_INIT( ) ( (void) 0 )
|
||||
#undef PSA_DONE
|
||||
#define PSA_DONE( ) ( (void) 0 )
|
||||
#endif
|
||||
|
||||
#define RSA_KEY_SIZE 512
|
||||
#define RSA_KEY_LEN 64
|
||||
|
||||
@ -208,7 +196,7 @@ exit:
|
||||
|
||||
mbedtls_pk_free( &pk ); /* redundant except upon error */
|
||||
mbedtls_pk_free( &pk2 );
|
||||
PSA_DONE( );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@ -770,7 +758,7 @@ void pk_ec_test_vec( int type, int id, data_t * key, data_t * hash,
|
||||
mbedtls_ecp_keypair *eckey;
|
||||
|
||||
mbedtls_pk_init( &pk );
|
||||
PSA_INIT( );
|
||||
USE_PSA_INIT( );
|
||||
|
||||
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
|
||||
|
||||
@ -787,7 +775,7 @@ void pk_ec_test_vec( int type, int id, data_t * key, data_t * hash,
|
||||
|
||||
exit:
|
||||
mbedtls_pk_free( &pk );
|
||||
PSA_DONE( );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@ -911,7 +899,7 @@ void pk_sign_verify( int type, int parameter, int sign_ret, int verify_ret )
|
||||
#endif
|
||||
|
||||
mbedtls_pk_init( &pk );
|
||||
PSA_INIT( );
|
||||
USE_PSA_INIT( );
|
||||
|
||||
memset( hash, 0x2a, sizeof hash );
|
||||
memset( sig, 0, sizeof sig );
|
||||
@ -973,7 +961,7 @@ exit:
|
||||
mbedtls_pk_restart_free( rs_ctx );
|
||||
#endif
|
||||
mbedtls_pk_free( &pk );
|
||||
PSA_DONE( );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@ -1302,6 +1290,6 @@ exit:
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
mbedtls_pk_free( &pk );
|
||||
PSA_DONE( );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -1,6 +1,12 @@
|
||||
RSA parameter validation
|
||||
rsa_invalid_param:
|
||||
|
||||
RSA init-free-free
|
||||
rsa_init_free:0
|
||||
|
||||
RSA init-free-init-free
|
||||
rsa_init_free:1
|
||||
|
||||
RSA PKCS1 Verify v1.5 CAVS #1
|
||||
depends_on:MBEDTLS_SHA1_C:MBEDTLS_PKCS1_V15
|
||||
# Good padding but wrong hash
|
||||
|
@ -466,6 +466,29 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void rsa_init_free( int reinit )
|
||||
{
|
||||
mbedtls_rsa_context ctx;
|
||||
|
||||
/* Double free is not explicitly documented to work, but we rely on it
|
||||
* even inside the library so that you can call mbedtls_rsa_free()
|
||||
* unconditionally on an error path without checking whether it has
|
||||
* already been called in the success path. */
|
||||
|
||||
mbedtls_rsa_init( &ctx, 0, 0 );
|
||||
mbedtls_rsa_free( &ctx );
|
||||
|
||||
if( reinit )
|
||||
mbedtls_rsa_init( &ctx, 0, 0 );
|
||||
mbedtls_rsa_free( &ctx );
|
||||
|
||||
/* This test case always succeeds, functionally speaking. A plausible
|
||||
* bug might trigger an invalid pointer dereference or a memory leak. */
|
||||
goto exit;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void mbedtls_rsa_pkcs1_sign( data_t * message_str, int padding_mode,
|
||||
int digest, int mod, int radix_P, char * input_P,
|
||||
|
@ -3836,9 +3836,7 @@ void ssl_tls_prf( int type, data_t * secret, data_t * random,
|
||||
if( output == NULL )
|
||||
goto exit;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
#endif
|
||||
USE_PSA_INIT( );
|
||||
|
||||
TEST_ASSERT( mbedtls_ssl_tls_prf( type, secret->x, secret->len,
|
||||
label, random->x, random->len,
|
||||
@ -3852,6 +3850,7 @@ void ssl_tls_prf( int type, data_t * secret, data_t * random,
|
||||
exit:
|
||||
|
||||
mbedtls_free( output );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -610,14 +610,12 @@ void x509_verify( char *crt_file, char *ca_file, char *crl_file,
|
||||
char * cn_name = NULL;
|
||||
const mbedtls_x509_crt_profile *profile;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
#endif
|
||||
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
mbedtls_x509_crt_init( &ca );
|
||||
mbedtls_x509_crl_init( &crl );
|
||||
|
||||
USE_PSA_INIT( );
|
||||
|
||||
if( strcmp( cn_name_str, "NULL" ) != 0 )
|
||||
cn_name = cn_name_str;
|
||||
|
||||
@ -669,6 +667,7 @@ exit:
|
||||
mbedtls_x509_crt_free( &crt );
|
||||
mbedtls_x509_crt_free( &ca );
|
||||
mbedtls_x509_crl_free( &crl );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@ -712,14 +711,12 @@ void x509_verify_callback( char *crt_file, char *ca_file, char *name,
|
||||
uint32_t flags = 0;
|
||||
verify_print_context vrfy_ctx;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
#endif
|
||||
|
||||
mbedtls_x509_crt_init( &crt );
|
||||
mbedtls_x509_crt_init( &ca );
|
||||
verify_print_init( &vrfy_ctx );
|
||||
|
||||
USE_PSA_INIT( );
|
||||
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 );
|
||||
|
||||
@ -737,6 +734,7 @@ void x509_verify_callback( char *crt_file, char *ca_file, char *name,
|
||||
exit:
|
||||
mbedtls_x509_crt_free( &crt );
|
||||
mbedtls_x509_crt_free( &ca );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@ -1024,10 +1022,6 @@ void mbedtls_x509_crt_verify_max( char *ca_file, char *chain_dir, int nb_int,
|
||||
uint32_t flags;
|
||||
mbedtls_x509_crt trusted, chain;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We expect chain_dir to contain certificates 00.crt, 01.crt, etc.
|
||||
* with NN.crt signed by NN-1.crt
|
||||
@ -1036,6 +1030,8 @@ void mbedtls_x509_crt_verify_max( char *ca_file, char *chain_dir, int nb_int,
|
||||
mbedtls_x509_crt_init( &trusted );
|
||||
mbedtls_x509_crt_init( &chain );
|
||||
|
||||
USE_PSA_INIT( );
|
||||
|
||||
/* Load trusted root */
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &trusted, ca_file ) == 0 );
|
||||
|
||||
@ -1055,6 +1051,7 @@ void mbedtls_x509_crt_verify_max( char *ca_file, char *chain_dir, int nb_int,
|
||||
exit:
|
||||
mbedtls_x509_crt_free( &chain );
|
||||
mbedtls_x509_crt_free( &trusted );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
@ -1069,13 +1066,11 @@ void mbedtls_x509_crt_verify_chain( char *chain_paths, char *trusted_ca,
|
||||
mbedtls_x509_crt trusted, chain;
|
||||
const mbedtls_x509_crt_profile *profile = NULL;
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
#endif
|
||||
|
||||
mbedtls_x509_crt_init( &chain );
|
||||
mbedtls_x509_crt_init( &trusted );
|
||||
|
||||
USE_PSA_INIT( );
|
||||
|
||||
while( ( act = mystrsep( &chain_paths, " " ) ) != NULL )
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &chain, act ) == 0 );
|
||||
TEST_ASSERT( mbedtls_x509_crt_parse_file( &trusted, trusted_ca ) == 0 );
|
||||
@ -1100,6 +1095,7 @@ void mbedtls_x509_crt_verify_chain( char *chain_paths, char *trusted_ca,
|
||||
exit:
|
||||
mbedtls_x509_crt_free( &trusted );
|
||||
mbedtls_x509_crt_free( &chain );
|
||||
USE_PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -6,12 +6,6 @@
|
||||
#include "mbedtls/oid.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
int mbedtls_rsa_decrypt_func( void *ctx, int mode, size_t *olen,
|
||||
const unsigned char *input, unsigned char *output,
|
||||
|
@ -358,6 +358,7 @@
|
||||
<ClCompile Include="..\..\tests\src\helpers.c" />
|
||||
<ClCompile Include="..\..\tests\src\psa_crypto_helpers.c" />
|
||||
<ClCompile Include="..\..\tests\src\random.c" />
|
||||
<ClCompile Include="..\..\tests\src\threading_helpers.c" />
|
||||
<ClCompile Include="..\..\3rdparty\everest\library\everest.c" />
|
||||
<ClCompile Include="..\..\3rdparty\everest\library\Hacl_Curve25519_joined.c" />
|
||||
<ClCompile Include="..\..\3rdparty\everest\library\x25519.c" />
|
||||
|
Loading…
Reference in New Issue
Block a user