Exemplo n.º 1
0
int s2n_connection_kill(struct s2n_connection *conn)
{
    conn->closed = 1;

    /* Delay between 10 and 30 seconds in nanoseconds */
    int64_t min = TEN_S, max = 3 * TEN_S;

    /* Keep track of the delay so that it can be enforced */
    conn->delay = min + s2n_public_random(max - min);

    /* Restart the write timer */
    GUARD(s2n_timer_start(conn->config, &conn->write_timer));

    if (conn->blinding == S2N_BUILT_IN_BLINDING) {
        struct timespec sleep_time = { .tv_sec = conn->delay / ONE_S, .tv_nsec = conn->delay % ONE_S };
        int r;

        do {
            r = nanosleep(&sleep_time, &sleep_time);
        }
        while (r != 0);
    }

    return 0;
}

const uint8_t *s2n_connection_get_ocsp_response(struct s2n_connection *conn, uint32_t *length)
{
    if (!length) {
        return NULL;
    }

    *length = conn->status_response.size;
    return conn->status_response.data;
}
Exemplo n.º 2
0
struct s2n_connection *s2n_connection_new(s2n_mode mode)
{
    struct s2n_blob blob;
    struct s2n_connection *conn;

    GUARD_PTR(s2n_alloc(&blob, sizeof(struct s2n_connection)));

    GUARD_PTR(s2n_blob_zero(&blob));

    if (mode == S2N_CLIENT) {
        /* At present s2n is not suitable for use in client mode, as it
         * does not perform any certificate validation. However it is useful
         * to use S2N in client mode for testing purposes. An environment
         * variable is required to be set for the client mode to work.
         */
        if (getenv("S2N_ENABLE_CLIENT_MODE") == NULL) {
            s2n_free(&blob);
            S2N_ERROR_PTR(S2N_ERR_CLIENT_MODE_DISABLED);
        }
    }

    /* Cast 'through' void to acknowledge that we are changing alignment,
     * which is ok, as blob.data is always aligned.
     */
    conn = (struct s2n_connection *)(void *)blob.data;
    conn->mode = mode;
    conn->blinding = S2N_BUILT_IN_BLINDING;
    conn->config = &s2n_default_config;

    /* Allocate the fixed-size stuffers */
    blob.data = conn->alert_in_data;
    blob.size = S2N_ALERT_LENGTH;

    GUARD_PTR(s2n_stuffer_init(&conn->alert_in, &blob));

    blob.data = conn->reader_alert_out_data;
    blob.size = S2N_ALERT_LENGTH;

    GUARD_PTR(s2n_stuffer_init(&conn->reader_alert_out, &blob));

    blob.data = conn->writer_alert_out_data;
    blob.size = S2N_ALERT_LENGTH;

    GUARD_PTR(s2n_stuffer_init(&conn->writer_alert_out, &blob));
    GUARD_PTR(s2n_stuffer_alloc(&conn->out, S2N_DEFAULT_RECORD_LENGTH));

    /* Initialize the growable stuffers. Zero length at first, but the resize
     * in _wipe will fix that 
     */
    blob.data = conn->header_in_data;
    blob.size = S2N_TLS_RECORD_HEADER_LENGTH;

    GUARD_PTR(s2n_stuffer_init(&conn->header_in, &blob));
    GUARD_PTR(s2n_stuffer_growable_alloc(&conn->in, 0));
    GUARD_PTR(s2n_stuffer_growable_alloc(&conn->handshake.io, 0));
    GUARD_PTR(s2n_connection_wipe(conn));
    GUARD_PTR(s2n_timer_start(conn->config, &conn->write_timer));

    return conn;
}
Exemplo n.º 3
0
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();
}
Exemplo n.º 4
0
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();
}