Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Unsets global libcrypto rand #4424

Merged
merged 7 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 };
maddeleine marked this conversation as resolved.
Show resolved Hide resolved
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);
Loading