diff --git a/tests/suites/test_suite_ctr_drbg.data b/tests/suites/test_suite_ctr_drbg.data index a72d8afa0d..70206e7d9a 100644 --- a/tests/suites/test_suite_ctr_drbg.data +++ b/tests/suites/test_suite_ctr_drbg.data @@ -1096,5 +1096,11 @@ ctr_drbg_seed_file:"no_such_dir/file":MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR CTR_DRBG Special Behaviours ctr_drbg_special_behaviours: +CTR_DRBG Threads: no reseed +ctr_drbg_threads:"1fafa98bc83d95e10f2d5ed339a553e1":10000 + +CTR_DRBG Threads: reseed +ctr_drbg_threads:"0d2dda60286dc738ddcc2dd3520bb988":25 + CTR_DRBG self test ctr_drbg_selftest: diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function index 066e70b352..bdf3dca59a 100644 --- a/tests/suites/test_suite_ctr_drbg.function +++ b/tests/suites/test_suite_ctr_drbg.function @@ -90,6 +90,19 @@ exit: mbedtls_ctr_drbg_free(&ctx); } +static const int thread_random_reps = 10; +void *thread_random_function( void* ctx ) +{ + unsigned char out[16]; + memset(out, 0, sizeof(out)); + + for(int i = 0; i < thread_random_reps; i++) { + TEST_EQUAL(mbedtls_ctr_drbg_random_with_add((mbedtls_ctr_drbg_context*) ctx, out, sizeof(out), NULL, 0), 0); + } + +exit: + return NULL; +} /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -325,6 +338,57 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */ +void ctr_drbg_threads(data_t *expected_result, int reseed_interval) +{ +#define THREAD_CNT 5 + pthread_t threads[THREAD_CNT]; + + unsigned char out[16]; + memset(out, 0, sizeof(out)); + + unsigned char entropy[1024]; + memset(entropy, 0, sizeof(entropy)); + + test_offset_idx = 0; + test_max_idx = sizeof(entropy); + + mbedtls_ctr_drbg_context ctx; + mbedtls_ctr_drbg_init(&ctx); + + mbedtls_ctr_drbg_set_reseed_interval(&ctx, reseed_interval); + + /* There are too many calls in this test to conveniently provide enough + * entropy for this to be on. Test cases can trigger reseeding by setting + * \p reseed_interval appropriately. */ + mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_OFF); + + TEST_EQUAL( + mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_entropy_func, entropy, NULL, 0), + 0); + + for (size_t i = 0; i < THREAD_CNT; i++) { + TEST_EQUAL( + pthread_create(&threads[i], NULL, + thread_random_function, (void*) &ctx), + 0); + } + + for (size_t i = 0; i < THREAD_CNT; i++) { + TEST_EQUAL(pthread_join(threads[i], NULL), 0); + } + + /* Take a last output for comparing and thus verifying the DRBG state */ + TEST_EQUAL(mbedtls_ctr_drbg_random(&ctx, out, sizeof(out)), 0); + + TEST_MEMORY_COMPARE(out, sizeof(out), expected_result->x, expected_result->len); + +exit: + mbedtls_ctr_drbg_free(&ctx); +} +#undef THREAD_CNT +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ void ctr_drbg_seed_file(char *path, int ret) {