Skip to content

Commit

Permalink
fix: Unsets global libcrypto rand (#4424)
Browse files Browse the repository at this point in the history
  • Loading branch information
maddeleine authored Feb 23, 2024
1 parent 7436ea0 commit 91ad940
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
7 changes: 1 addition & 6 deletions tests/s2n_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,12 @@ int test_count;
* not initialise at the start of the test. Useful for tests that e.g spawn a
* number of independent childs at the start of a unit test and where you want
* each child to have its own independently initialised s2n.
*
* BEGIN_TEST() prints unit test information to stdout. But this often gets
* buffered by the kernel and will then be flushed in each child spawned. The
* result is a number of repeated messages being send to stdout and, in turn,
* appear in the logs. At the moment, we think this is better than risking not
* having any printing at all.
*/
#define BEGIN_TEST_NO_INIT() \
do { \
test_count = 0; \
fprintf(stdout, "Running %-50s ... ", __FILE__); \
fflush(stdout); \
EXPECT_SUCCESS_WITHOUT_COUNT(s2n_in_unit_test_set(true)); \
S2N_TEST_OPTIONALLY_ENABLE_FIPS_MODE(); \
} while(0)
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/s2n_random_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,30 @@ static int s2n_random_rand_bytes_after_cleanup_cb(struct random_test_case *test_
return S2N_SUCCESS;
}

static int s2n_random_rand_bytes_before_init(struct random_test_case *test_case)
{
#if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND
/* Calling RAND_bytes will set a global random method */
unsigned char rndbytes[16] = { 0 };
EXPECT_EQUAL(RAND_bytes(rndbytes, sizeof(rndbytes)), 1);
const RAND_METHOD *rand_method = RAND_get_rand_method();
EXPECT_NOT_NULL(rand_method);
EXPECT_NOT_EQUAL(rand_method->bytes, s2n_openssl_compat_rand);

EXPECT_SUCCESS(s2n_init());

/* The global random method is overridden after calling s2n_init() */
const RAND_METHOD *custom_rand_method = RAND_get_rand_method();
EXPECT_NOT_NULL(custom_rand_method);
EXPECT_EQUAL(custom_rand_method->bytes, s2n_openssl_compat_rand);

/* RAND_bytes is still successful */
EXPECT_EQUAL(RAND_bytes(rndbytes, sizeof(rndbytes)), 1);

#endif
return S2N_SUCCESS;
}

static int s2n_random_invalid_urandom_fd_cb(struct random_test_case *test_case)
{
EXPECT_SUCCESS(s2n_disable_atexit());
Expand Down Expand Up @@ -862,6 +886,7 @@ struct random_test_case random_test_cases[] = {
{ "Test failure.", s2n_random_test_case_failure_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, 1 },
{ "Test libcrypto's RAND engine is reset correctly after manual s2n_cleanup()", s2n_random_rand_bytes_after_cleanup_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS },
{ "Test getting entropy with an invalid file descriptor", s2n_random_invalid_urandom_fd_cb, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS },
{ "Test libcrypto's global RAND is unset after calling s2n_init()", s2n_random_rand_bytes_before_init, CLONE_TEST_DETERMINE_AT_RUNTIME, EXIT_SUCCESS },
};

int main(int argc, char **argv)
Expand Down
3 changes: 3 additions & 0 deletions utils/s2n_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,9 @@ S2N_RESULT s2n_rand_init(void)
return S2N_RESULT_OK;
}

/* Unset any existing random engine */
RESULT_GUARD_OSSL(RAND_set_rand_engine(NULL), S2N_ERR_OPEN_RANDOM);

/* Create an engine */
ENGINE *e = ENGINE_new();

Expand Down
1 change: 1 addition & 0 deletions utils/s2n_random.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ S2N_RESULT s2n_get_public_random_bytes_used(uint64_t *bytes_used);
S2N_RESULT s2n_get_private_random_data(struct s2n_blob *blob);
S2N_RESULT s2n_get_private_random_bytes_used(uint64_t *bytes_used);
S2N_RESULT s2n_public_random(int64_t max, uint64_t *output);
int s2n_openssl_compat_rand(unsigned char *buf, int num);

0 comments on commit 91ad940

Please sign in to comment.