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(); }
int s2n_dhe_server_key_send(struct s2n_connection *conn, struct s2n_blob *data_to_sign) { struct s2n_stuffer *out = &conn->handshake.io; /* Duplicate the DH key from the config */ GUARD(s2n_dh_params_copy(conn->config->dhparams, &conn->secure.server_dh_params)); /* Generate an ephemeral key */ GUARD(s2n_dh_generate_ephemeral_key(&conn->secure.server_dh_params)); /* Write it out and calculate the data to sign later */ GUARD(s2n_dh_params_to_p_g_Ys(&conn->secure.server_dh_params, out, data_to_sign)); return 0; }
int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key) { struct s2n_dh_params client_params; uint8_t *client_pub_key; uint16_t client_pub_key_size; int shared_key_size; GUARD(s2n_dh_params_check(server_dh_params)); GUARD(s2n_dh_params_copy(server_dh_params, &client_params)); GUARD(s2n_dh_generate_ephemeral_key(&client_params)); GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh))); const BIGNUM *client_pub_key_bn = s2n_get_Ys_dh_param(&client_params); client_pub_key_size = BN_num_bytes(client_pub_key_bn); GUARD(s2n_stuffer_write_uint16(Yc_out, client_pub_key_size)); client_pub_key = s2n_stuffer_raw_write(Yc_out, client_pub_key_size); if (client_pub_key == NULL) { GUARD(s2n_free(shared_key)); GUARD(s2n_dh_params_free(&client_params)); S2N_ERROR(S2N_ERR_DH_WRITING_PUBLIC_KEY); } if (BN_bn2bin(client_pub_key_bn, client_pub_key) != client_pub_key_size) { GUARD(s2n_free(shared_key)); GUARD(s2n_dh_params_free(&client_params)); S2N_ERROR(S2N_ERR_DH_COPYING_PUBLIC_KEY); } /* server_dh_params already validated */ const BIGNUM *server_pub_key_bn = s2n_get_Ys_dh_param(server_dh_params); shared_key_size = DH_compute_key(shared_key->data, server_pub_key_bn, client_params.dh); if (shared_key_size < 0) { GUARD(s2n_free(shared_key)); GUARD(s2n_dh_params_free(&client_params)); S2N_ERROR(S2N_ERR_DH_SHARED_SECRET); } shared_key->size = shared_key_size; GUARD(s2n_dh_params_free(&client_params)); return 0; }
static int s2n_dhe_server_key_send(struct s2n_connection *conn) { struct s2n_blob serverDHparams, signature; struct s2n_stuffer *out = &conn->handshake.io; struct s2n_hash_state signature_hash; /* Duplicate the DH key from the config */ GUARD(s2n_dh_params_copy(conn->config->dhparams, &conn->secure.server_dh_params)); /* Generate an ephemeral key */ GUARD(s2n_dh_generate_ephemeral_key(&conn->secure.server_dh_params)); /* Write it out */ GUARD(s2n_dh_params_to_p_g_Ys(&conn->secure.server_dh_params, out, &serverDHparams)); if (conn->actual_protocol_version == S2N_TLS12) { GUARD(s2n_stuffer_write_uint8(out, TLS_HASH_ALGORITHM_SHA1)); GUARD(s2n_stuffer_write_uint8(out, TLS_SIGNATURE_ALGORITHM_RSA)); } GUARD(s2n_hash_init(&signature_hash, conn->secure.signature_digest_alg)); GUARD(s2n_hash_update(&signature_hash, conn->secure.client_random, S2N_TLS_RANDOM_DATA_LEN)); GUARD(s2n_hash_update(&signature_hash, conn->secure.server_random, S2N_TLS_RANDOM_DATA_LEN)); GUARD(s2n_hash_update(&signature_hash, serverDHparams.data, serverDHparams.size)); signature.size = s2n_rsa_private_encrypted_size(&conn->config->cert_and_key_pairs->private_key); GUARD(s2n_stuffer_write_uint16(out, signature.size)); signature.data = s2n_stuffer_raw_write(out, signature.size); notnull_check(signature.data); if (s2n_rsa_sign(&conn->config->cert_and_key_pairs->private_key, &signature_hash, &signature) < 0) { S2N_ERROR(S2N_ERR_DH_FAILED_SIGNING); } return 0; }