int main(int argc, char **argv) { struct s2n_stuffer dhparams_in, dhparams_out; struct s2n_dh_params dh_params; struct s2n_blob b; BEGIN_TEST(); EXPECT_EQUAL(s2n_get_private_random_bytes_used(), 0); /* Parse the DH params */ b.data = dhparams; b.size = sizeof(dhparams); EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_in, sizeof(dhparams))); EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_out, sizeof(dhparams))); EXPECT_SUCCESS(s2n_stuffer_write(&dhparams_in, &b)); EXPECT_SUCCESS(s2n_stuffer_dhparams_from_pem(&dhparams_in, &dhparams_out)); b.size = s2n_stuffer_data_available(&dhparams_out); b.data = s2n_stuffer_raw_read(&dhparams_out, b.size); EXPECT_SUCCESS(s2n_pkcs3_to_dh_params(&dh_params, &b)); EXPECT_SUCCESS(s2n_dh_generate_ephemeral_key(&dh_params)); /* Verify that our DRBG is called and that over-riding works */ EXPECT_NOT_EQUAL(s2n_get_private_random_bytes_used(), 0); EXPECT_SUCCESS(s2n_dh_params_free(&dh_params)); EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_out)); EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_in)); END_TEST(); }
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; }
int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size) { GUARD(s2n_stuffer_alloc(stuffer, size)); stuffer->growable = 1; return 0; }
int main(int argc, char **argv) { uint8_t u8; uint16_t u16; uint32_t u32; uint32_t stuffer_size = nondet_uint32(); __CPROVER_assume(stuffer_size > 0); uint32_t entropy_size = nondet_uint32(); __CPROVER_assume(entropy_size > 0); uint8_t entropy[entropy_size]; struct s2n_stuffer stuffer; GUARD(s2n_stuffer_alloc(&stuffer, stuffer_size)); struct s2n_blob in = {.data = entropy,.size = entropy_size}; GUARD(s2n_stuffer_write(&stuffer, &in)); GUARD(s2n_stuffer_wipe(&stuffer)); while(nondet_bool()) { GUARD(s2n_stuffer_write_uint8(&stuffer, nondet_uint64())); } while(nondet_bool()) { GUARD(s2n_stuffer_read_uint8(&stuffer, &u8)); } GUARD(s2n_stuffer_wipe(&stuffer)); while(nondet_bool()) { GUARD(s2n_stuffer_write_uint16(&stuffer, nondet_uint64())); } while(nondet_bool()) { GUARD(s2n_stuffer_read_uint16(&stuffer, &u16)); } GUARD(s2n_stuffer_wipe(&stuffer)); while(nondet_bool()) { GUARD(s2n_stuffer_write_uint24(&stuffer, nondet_uint64())); } while(nondet_bool()) { GUARD(s2n_stuffer_read_uint24(&stuffer, &u32)); } GUARD(s2n_stuffer_wipe(&stuffer)); while(nondet_bool()) { GUARD(s2n_stuffer_write_uint32(&stuffer, nondet_uint64())); } while(nondet_bool()) { GUARD(s2n_stuffer_read_uint32(&stuffer, &u32)); } GUARD(s2n_stuffer_free(&stuffer)); }
/** * Private helper: write n (up to 64) bits of hex data */ static int s2n_stuffer_write_n_bits_hex(struct s2n_stuffer *stuffer, uint8_t n, uint64_t u) { uint8_t hex_data[16] = { 0 }; struct s2n_blob b = { .data = hex_data, .size = n / 4 }; lte_check(n, 64); for (int i = b.size; i > 0; i--) { b.data[i - 1] = hex[u & 0x0f]; u >>= 4; } GUARD(s2n_stuffer_write(stuffer, &b)); return 0; } int s2n_stuffer_write_uint64_hex(struct s2n_stuffer *stuffer, uint64_t u) { return s2n_stuffer_write_n_bits_hex(stuffer, 64, u); } int s2n_stuffer_write_uint32_hex(struct s2n_stuffer *stuffer, uint32_t u) { return s2n_stuffer_write_n_bits_hex(stuffer, 32, u); } int s2n_stuffer_write_uint16_hex(struct s2n_stuffer *stuffer, uint16_t u) { return s2n_stuffer_write_n_bits_hex(stuffer, 16, u); } int s2n_stuffer_write_uint8_hex(struct s2n_stuffer *stuffer, uint8_t u) { return s2n_stuffer_write_n_bits_hex(stuffer, 8, u); } int s2n_stuffer_alloc_ro_from_hex_string(struct s2n_stuffer *stuffer, const char *str) { if (strlen(str) % 2) { S2N_ERROR(S2N_ERR_SIZE_MISMATCH); } GUARD(s2n_stuffer_alloc(stuffer, strlen(str) / 2)); for (int i = 0; i < strlen(str); i += 2) { uint8_t u = 0; if (str[i] >= '0' && str[i] <= '9') { u = str[i] - '0'; } else if (str[i] >= 'a' && str[i] <= 'f') { u = str[i] - 'a' + 10; } else if (str[i] >= 'A' && str[i] <= 'F') { u = str[i] - 'A' + 10; } else { S2N_ERROR(S2N_ERR_BAD_MESSAGE); } u <<= 4; if (str[i + 1] >= '0' && str[i + 1] <= '9') { u |= str[i + 1] - '0'; } else if (str[i + 1] >= 'a' && str[i + 1] <= 'f') { u |= str[i + 1] - 'a' + 10; } else if (str[i + 1] >= 'A' && str[i + 1] <= 'F') { u |= str[i + 1] - 'A' + 10; } else { S2N_ERROR(S2N_ERR_BAD_MESSAGE); } GUARD(s2n_stuffer_write_uint8(stuffer, u)); } return 0; }
int main(int argc, char **argv) { BEGIN_TEST(); EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0)); /* Part 1 setup a client and server connection with everything they need for a key exchange */ struct s2n_connection *client_conn, *server_conn; EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT)); EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER)); struct s2n_config *server_config, *client_config; client_config = s2n_fetch_unsafe_client_testing_config(); GUARD(s2n_connection_set_config(client_conn, client_config)); /* Part 1.1 setup server's keypair and the give the client the certificate */ char *cert_chain; char *private_key; char *client_chain; EXPECT_NOT_NULL(cert_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(private_key = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(client_chain = malloc(S2N_MAX_TEST_PEM_SIZE)); EXPECT_NOT_NULL(server_config = s2n_config_new()); EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_CERT_CHAIN, cert_chain, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_KEY, private_key, S2N_MAX_TEST_PEM_SIZE)); EXPECT_SUCCESS(s2n_read_test_pem(S2N_RSA_2048_PKCS1_LEAF_CERT, client_chain, S2N_MAX_TEST_PEM_SIZE)); struct s2n_cert_chain_and_key *chain_and_key; EXPECT_NOT_NULL(chain_and_key = s2n_cert_chain_and_key_new()); EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(chain_and_key, cert_chain, private_key)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(server_config, chain_and_key)); EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config)); GUARD(s2n_set_signature_hash_pair_from_preference_list(server_conn, &server_conn->handshake_params.client_sig_hash_algs, &server_conn->secure.conn_hash_alg, &server_conn->secure.conn_sig_alg)); DEFER_CLEANUP(struct s2n_stuffer certificate_in = {{0}}, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, S2N_MAX_TEST_PEM_SIZE)); DEFER_CLEANUP(struct s2n_stuffer certificate_out = {{0}}, s2n_stuffer_free); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, S2N_MAX_TEST_PEM_SIZE)); struct s2n_blob temp_blob; temp_blob.data = (uint8_t *) client_chain; temp_blob.size = strlen(client_chain) + 1; EXPECT_SUCCESS(s2n_stuffer_write(&certificate_in, &temp_blob)); EXPECT_SUCCESS(s2n_stuffer_certificate_from_pem(&certificate_in, &certificate_out)); temp_blob.size = s2n_stuffer_data_available(&certificate_out); temp_blob.data = s2n_stuffer_raw_read(&certificate_out, temp_blob.size); s2n_cert_type cert_type; EXPECT_SUCCESS(s2n_asn1der_to_public_key_and_type(&client_conn->secure.server_public_key, &cert_type, &temp_blob)); server_conn->handshake_params.our_chain_and_key = chain_and_key; EXPECT_SUCCESS(setup_connection(server_conn)); EXPECT_SUCCESS(setup_connection(client_conn)); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Read the seed from the RSP_FILE and create the DRBG for the test. Since the seed is the same (and prediction * resistance is off) all calls to generate random data will return the same sequence. Thus the server always * generates the same ECDHE point and KEM public key, the client does the same. */ FILE *kat_file = fopen(RSP_FILE_NAME, "r"); EXPECT_NOT_NULL(kat_file); EXPECT_SUCCESS(s2n_alloc(&kat_entropy_blob, 48)); EXPECT_SUCCESS(ReadHex(kat_file, kat_entropy_blob.data, 48, "seed = ")); struct s2n_drbg drbg = {.entropy_generator = &s2n_entropy_generator}; s2n_stack_blob(personalization_string, 32, 32); EXPECT_SUCCESS(s2n_drbg_instantiate(&drbg, &personalization_string, S2N_DANGEROUS_AES_256_CTR_NO_DF_NO_PR)); EXPECT_SUCCESS(s2n_set_private_drbg_for_test(drbg)); #endif /* Part 2 server sends key first */ EXPECT_SUCCESS(s2n_server_key_send(server_conn)); /* Part 2.1 verify the results as best we can */ EXPECT_EQUAL(server_conn->handshake.io.write_cursor, SERVER_KEY_MESSAGE_LENGTH); struct s2n_blob server_key_message = {.size = SERVER_KEY_MESSAGE_LENGTH, .data = s2n_stuffer_raw_read(&server_conn->handshake.io, SERVER_KEY_MESSAGE_LENGTH)}; #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Part 2.1.1 if we're running in known answer mode check the server's key exchange message matches the expected value */ uint8_t expected_server_key_message[SERVER_KEY_MESSAGE_LENGTH]; EXPECT_SUCCESS(ReadHex(kat_file, expected_server_key_message, SERVER_KEY_MESSAGE_LENGTH, "expected_server_key_exchange = ")); EXPECT_BYTEARRAY_EQUAL(expected_server_key_message, server_key_message.data, SERVER_KEY_MESSAGE_LENGTH); #endif /* Part 2.2 copy server's message to the client's stuffer */ s2n_stuffer_write(&client_conn->handshake.io, &server_key_message); /* Part 3 client recvs the server's key and sends the client key exchange message */ EXPECT_SUCCESS(s2n_server_key_recv(client_conn)); EXPECT_SUCCESS(s2n_client_key_send(client_conn)); /* Part 3.1 verify the results as best we can */ EXPECT_EQUAL(client_conn->handshake.io.write_cursor - client_conn->handshake.io.read_cursor, CLIENT_KEY_MESSAGE_LENGTH); struct s2n_blob client_key_message = {.size = CLIENT_KEY_MESSAGE_LENGTH, .data = s2n_stuffer_raw_read(&client_conn->handshake.io, CLIENT_KEY_MESSAGE_LENGTH)}; #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Part 3.1.1 if we're running in known answer mode check the client's key exchange message matches the expected value */ uint8_t expected_client_key_message[CLIENT_KEY_MESSAGE_LENGTH]; EXPECT_SUCCESS(ReadHex(kat_file, expected_client_key_message, CLIENT_KEY_MESSAGE_LENGTH, "expected_client_key_exchange = ")); EXPECT_BYTEARRAY_EQUAL(expected_client_key_message, client_key_message.data, CLIENT_KEY_MESSAGE_LENGTH); #endif /* Part 3.2 copy the client's message back to the server's stuffer */ s2n_stuffer_write(&server_conn->handshake.io, &client_key_message); /* Part 4 server receives the client's message */ EXPECT_SUCCESS(s2n_client_key_recv(server_conn)); /* Part 4.1 verify results as best we can, the client and server should at least have the same master secret */ EXPECT_BYTEARRAY_EQUAL(server_conn->secure.master_secret, client_conn->secure.master_secret, S2N_TLS_SECRET_LEN); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Part 4.1.1 if we're running in known answer mode check that both the client and server got the expected master secret * from the RSP_FILE */ uint8_t expected_master_secret[S2N_TLS_SECRET_LEN]; EXPECT_SUCCESS(ReadHex(kat_file, expected_master_secret, S2N_TLS_SECRET_LEN, "expected_master_secret = ")); EXPECT_BYTEARRAY_EQUAL(expected_master_secret, client_conn->secure.master_secret, S2N_TLS_SECRET_LEN); EXPECT_BYTEARRAY_EQUAL(expected_master_secret, server_conn->secure.master_secret, S2N_TLS_SECRET_LEN); #endif EXPECT_SUCCESS(s2n_cert_chain_and_key_free(chain_and_key)); EXPECT_SUCCESS(s2n_connection_free(client_conn)); EXPECT_SUCCESS(s2n_connection_free(server_conn)); EXPECT_SUCCESS(s2n_config_free(server_config)); free(cert_chain); free(client_chain); free(private_key); #if S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND /* Extra cleanup needed for the known answer test */ fclose(kat_file); #endif END_TEST(); }
int main(int argc, char **argv) { struct s2n_stuffer certificate_in, certificate_out; struct s2n_stuffer dhparams_in, dhparams_out; struct s2n_stuffer rsa_key_in, rsa_key_out; struct s2n_blob b; BEGIN_TEST(); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_in, sizeof(certificate))); EXPECT_SUCCESS(s2n_stuffer_alloc(&certificate_out, sizeof(certificate))); EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_in, sizeof(dhparams))); EXPECT_SUCCESS(s2n_stuffer_alloc(&dhparams_out, sizeof(dhparams))); EXPECT_SUCCESS(s2n_stuffer_alloc(&rsa_key_in, sizeof(private_key))); EXPECT_SUCCESS(s2n_stuffer_alloc(&rsa_key_out, sizeof(private_key))); b.data = certificate; b.size = sizeof(certificate); EXPECT_SUCCESS(s2n_stuffer_write(&certificate_in, &b)); b.data = private_key; b.size = sizeof(private_key); EXPECT_SUCCESS(s2n_stuffer_write(&rsa_key_in, &b)); b.data = dhparams; b.size = sizeof(dhparams); EXPECT_SUCCESS(s2n_stuffer_write(&dhparams_in, &b)); EXPECT_SUCCESS(s2n_stuffer_certificate_from_pem(&certificate_in, &certificate_out)); EXPECT_SUCCESS(s2n_stuffer_rsa_private_key_from_pem(&rsa_key_in, &rsa_key_out)); EXPECT_SUCCESS(s2n_stuffer_dhparams_from_pem(&dhparams_in, &dhparams_out)); struct s2n_rsa_private_key priv_key; struct s2n_rsa_public_key pub_key; b.size = s2n_stuffer_data_available(&certificate_out); b.data = s2n_stuffer_raw_read(&certificate_out, b.size); EXPECT_SUCCESS(s2n_asn1der_to_rsa_public_key(&pub_key, &b)); b.size = s2n_stuffer_data_available(&rsa_key_out); b.data = s2n_stuffer_raw_read(&rsa_key_out, b.size); EXPECT_SUCCESS(s2n_asn1der_to_rsa_private_key(&priv_key, &b)); EXPECT_SUCCESS(s2n_rsa_keys_match(&pub_key, &priv_key)); struct s2n_connection *conn; EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_SERVER)); EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(conn->config, (char *)chain, (char *)private_key)); struct s2n_dh_params dh_params; b.size = s2n_stuffer_data_available(&dhparams_out); b.data = s2n_stuffer_raw_read(&dhparams_out, b.size); EXPECT_SUCCESS(s2n_pkcs3_to_dh_params(&dh_params, &b)); EXPECT_SUCCESS(s2n_config_add_dhparams(conn->config, (char *)dhparams)); /* Try signing and verification with RSA */ uint8_t inputpad[] = "Hello world!"; struct s2n_blob signature; struct s2n_hash_state tls10_one, tls10_two, tls12_one, tls12_two; EXPECT_SUCCESS(s2n_hash_init(&tls10_one, S2N_HASH_MD5_SHA1)); EXPECT_SUCCESS(s2n_hash_init(&tls10_two, S2N_HASH_MD5_SHA1)); EXPECT_SUCCESS(s2n_hash_init(&tls12_one, S2N_HASH_SHA1)); EXPECT_SUCCESS(s2n_hash_init(&tls12_two, S2N_HASH_SHA1)); EXPECT_SUCCESS(s2n_alloc(&signature, s2n_rsa_public_encrypted_size(&pub_key))); EXPECT_SUCCESS(s2n_hash_update(&tls10_one, inputpad, sizeof(inputpad))); EXPECT_SUCCESS(s2n_hash_update(&tls10_two, inputpad, sizeof(inputpad))); EXPECT_SUCCESS(s2n_rsa_sign(&priv_key, &tls10_one, &signature)); EXPECT_SUCCESS(s2n_rsa_verify(&pub_key, &tls10_two, &signature)); EXPECT_SUCCESS(s2n_hash_update(&tls12_one, inputpad, sizeof(inputpad))); EXPECT_SUCCESS(s2n_hash_update(&tls12_two, inputpad, sizeof(inputpad))); EXPECT_SUCCESS(s2n_rsa_sign(&priv_key, &tls12_one, &signature)); EXPECT_SUCCESS(s2n_rsa_verify(&pub_key, &tls12_two, &signature)); EXPECT_SUCCESS(s2n_dh_params_free(&dh_params)); EXPECT_SUCCESS(s2n_rsa_private_key_free(&priv_key)); EXPECT_SUCCESS(s2n_rsa_public_key_free(&pub_key)); EXPECT_SUCCESS(s2n_config_free_dhparams(conn->config)); EXPECT_SUCCESS(s2n_config_free_cert_chain_and_key(conn->config)); EXPECT_SUCCESS(s2n_connection_free(conn)); EXPECT_SUCCESS(s2n_free(&signature)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_in)); EXPECT_SUCCESS(s2n_stuffer_free(&certificate_out)); EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_in)); EXPECT_SUCCESS(s2n_stuffer_free(&dhparams_out)); EXPECT_SUCCESS(s2n_stuffer_free(&rsa_key_in)); EXPECT_SUCCESS(s2n_stuffer_free(&rsa_key_out)); END_TEST(); }