int main(int argc, char **argv) { struct s2n_timer timer; uint64_t nanoseconds; BEGIN_TEST(); /* First: Perform some tests using the real clock */ EXPECT_SUCCESS(s2n_timer_start(&timer)); EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds)); EXPECT_TRUE(nanoseconds < 1000000000); EXPECT_SUCCESS(s2n_timer_elapsed(&timer, &nanoseconds)); EXPECT_TRUE(nanoseconds < 1000000000); EXPECT_SUCCESS(sleep(1)); EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds)); EXPECT_TRUE(nanoseconds > 1000000000); EXPECT_TRUE(nanoseconds < 2000000000); EXPECT_SUCCESS(sleep(1)); EXPECT_SUCCESS(s2n_timer_elapsed(&timer, &nanoseconds)); EXPECT_TRUE(nanoseconds > 1000000000); EXPECT_TRUE(nanoseconds < 2000000000); #if !defined(__APPLE__) || !defined(__MACH__) /* Next: perform some tests around timespec boundaries */ /* Pretend that there were 999,999,999 nanoseconds elapsed in the * previously measured instant. Keep reseting the timer until * the second progresses from that instant, and there are also * less than 999,999,999 nanoseconds elapsed. * * This sets up a situation in which the tv_sec field causes time * to move "forwards", and tv_nsec causes it to move backwards. * e.g. * * previous_time = 10 * * timer.time.tv_sec = 11 * timer.time.tv_nsec = 123456789; * * delta will be: * (11 - 10) * 1000000000 * + (123456789 - 999999999) * * = 123456790 (same as 1 + 123456789) */ time_t previous_time; do { previous_time = timer.time.tv_sec; timer.time.tv_nsec = 999999999; EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds)); } while(previous_time != (timer.time.tv_sec - 1) || timer.time.tv_nsec == 999999999); EXPECT_TRUE(nanoseconds < 1000000000); EXPECT_TRUE(nanoseconds == 1 + timer.time.tv_nsec); /* Now we perform the oppossite test: make sure that the previous value for * nsec is smaller than the later one */ do { previous_time = timer.time.tv_sec; timer.time.tv_nsec = 0; EXPECT_SUCCESS(s2n_timer_reset(&timer, &nanoseconds)); } while(previous_time != (timer.time.tv_sec - 1) || timer.time.tv_nsec == 0); EXPECT_TRUE(nanoseconds > 1000000000); EXPECT_TRUE(nanoseconds < 2000000000); EXPECT_TRUE(nanoseconds == 1000000000 + timer.time.tv_nsec); #endif END_TEST(); }
int main(int argc, char **argv) { uint8_t data[256] = { 0 }; struct s2n_drbg drbg = {{ 0 }}; struct s2n_blob blob = {.data = data, .size = 64 }; struct s2n_timer timer; uint64_t drbg_nanoseconds; uint64_t urandom_nanoseconds; struct s2n_stuffer nist_reference_personalization_strings; struct s2n_stuffer nist_reference_returned_bits; struct s2n_stuffer nist_reference_values; struct s2n_config *config; BEGIN_TEST(); EXPECT_NOT_NULL(config = s2n_config_new()) /* Open /dev/urandom */ EXPECT_TRUE(entropy_fd = open("/dev/urandom", O_RDONLY)); /* Convert the hex entropy data into binary */ EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_entropy, nist_reference_entropy_hex)); EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_personalization_strings, nist_reference_personalization_strings_hex)); EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_returned_bits, nist_reference_returned_bits_hex)); EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&nist_reference_values, nist_reference_values_hex)); /* Check everything against the NIST vectors */ for (int i = 0; i < 14; i++) { uint8_t ps[32]; struct s2n_drbg nist_drbg = { .entropy_generator = nist_fake_urandom_data }; struct s2n_blob personalization_string = {.data = ps, .size = 32}; /* Read the next personalization string */ EXPECT_SUCCESS(s2n_stuffer_read(&nist_reference_personalization_strings, &personalization_string)); /* Instantiate the DRBG */ EXPECT_SUCCESS(s2n_drbg_instantiate(&nist_drbg, &personalization_string)); uint8_t nist_v[16]; GUARD(s2n_stuffer_read_bytes(&nist_reference_values, nist_v, sizeof(nist_v))); EXPECT_TRUE(memcmp(nist_v, nist_drbg.v, sizeof(nist_drbg.v)) == 0); /* Generate 512 bits (FIRST CALL) */ uint8_t out[64]; struct s2n_blob generated = {.data = out, .size = 64 }; EXPECT_SUCCESS(s2n_drbg_generate(&nist_drbg, &generated)); GUARD(s2n_stuffer_read_bytes(&nist_reference_values, nist_v, sizeof(nist_v))); EXPECT_TRUE(memcmp(nist_v, nist_drbg.v, sizeof(nist_drbg.v)) == 0); /* Generate another 512 bits (SECOND CALL) */ EXPECT_SUCCESS(s2n_drbg_generate(&nist_drbg, &generated)); GUARD(s2n_stuffer_read_bytes(&nist_reference_values, nist_v, sizeof(nist_v))); EXPECT_TRUE(memcmp(nist_v, nist_drbg.v, sizeof(nist_drbg.v)) == 0); uint8_t nist_returned_bits[64]; GUARD(s2n_stuffer_read_bytes(&nist_reference_returned_bits, nist_returned_bits, sizeof(nist_returned_bits))); EXPECT_TRUE(memcmp(nist_returned_bits, out, sizeof(nist_returned_bits)) == 0); EXPECT_SUCCESS(s2n_drbg_wipe(&nist_drbg)); } EXPECT_SUCCESS(s2n_drbg_instantiate(&drbg, &blob)); /* Use the DRBG for 32MB of data */ EXPECT_SUCCESS(s2n_timer_start(config, &timer)); for (int i = 0; i < 500000; i++) { EXPECT_SUCCESS(s2n_drbg_generate(&drbg, &blob)); } EXPECT_SUCCESS(s2n_timer_reset(config, &timer, &drbg_nanoseconds)); /* Use urandom for 32MB of data */ EXPECT_SUCCESS(s2n_timer_start(config, &timer)); for (int i = 0; i < 500000; i++) { EXPECT_SUCCESS(s2n_get_urandom_data(&blob)); } EXPECT_SUCCESS(s2n_timer_reset(config, &timer, &urandom_nanoseconds)); /* Confirm that the DRBG is faster than urandom */ EXPECT_TRUE(drbg_nanoseconds < urandom_nanoseconds); /* NOTE: s2n_random_test also includes monobit tests for this DRBG */ /* the DRBG state is 128 bytes, test that we can get more than that */ blob.size = 129; for (int i = 0; i < 10; i++) { EXPECT_SUCCESS(s2n_drbg_generate(&drbg, &blob)); } EXPECT_SUCCESS(s2n_drbg_wipe(&drbg)); EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_entropy)); EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_personalization_strings)); EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_returned_bits)); EXPECT_SUCCESS(s2n_stuffer_free(&nist_reference_values)); END_TEST(); }