Skip to content

Commit

Permalink
Allocate s2n_crypto_parameters separately
Browse files Browse the repository at this point in the history
  • Loading branch information
lrstewart committed Aug 26, 2022
1 parent 990f129 commit 0754e5c
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 196 deletions.
4 changes: 2 additions & 2 deletions tests/unit/s2n_connection_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ int main(int argc, char **argv)
*/
{
/* Carefully consider any increases to this number. */
const uint16_t max_connection_size = 9050;
const uint16_t min_connection_size = max_connection_size * 0.75;
const uint16_t max_connection_size = 4150;
const uint16_t min_connection_size = max_connection_size * 0.9;

size_t connection_size = sizeof(struct s2n_connection);

Expand Down
130 changes: 19 additions & 111 deletions tls/s2n_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "tls/s2n_alerts.h"
#include "tls/s2n_cipher_suites.h"
#include "tls/s2n_connection.h"
#include "tls/s2n_connection_evp_digests.h"
#include "tls/s2n_handshake.h"
#include "tls/s2n_kem.h"
#include "tls/s2n_internal.h"
Expand All @@ -59,28 +58,6 @@
#define S2N_SET_KEY_SHARE_LIST_EMPTY(keyshares) (keyshares |= 1)
#define S2N_SET_KEY_SHARE_REQUEST(keyshares, i) (keyshares |= ( 1 << ( i + 1 )))

static int s2n_connection_new_hmacs(struct s2n_connection *conn)
{
/* Allocate long-term memory for the Connection's HMAC states */
POSIX_GUARD(s2n_hmac_new(&conn->initial->client_record_mac));
POSIX_GUARD(s2n_hmac_new(&conn->initial->server_record_mac));
POSIX_GUARD(s2n_hmac_new(&conn->secure->client_record_mac));
POSIX_GUARD(s2n_hmac_new(&conn->secure->server_record_mac));

return 0;
}

static int s2n_connection_init_hmacs(struct s2n_connection *conn)
{
/* Initialize all of the Connection's HMAC states */
POSIX_GUARD(s2n_hmac_init(&conn->initial->client_record_mac, S2N_HMAC_NONE, NULL, 0));
POSIX_GUARD(s2n_hmac_init(&conn->initial->server_record_mac, S2N_HMAC_NONE, NULL, 0));
POSIX_GUARD(s2n_hmac_init(&conn->secure->client_record_mac, S2N_HMAC_NONE, NULL, 0));
POSIX_GUARD(s2n_hmac_init(&conn->secure->server_record_mac, S2N_HMAC_NONE, NULL, 0));

return 0;
}

/* Allocates and initializes memory for a new connection.
*
* Since customers can reuse a connection, ensure that values on the connection are
Expand All @@ -101,10 +78,6 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode)
/* `mode` is initialized here since its passed in as a parameter. */
conn->mode = mode;

/* TODO: swap this to a real heap allocation */
conn->initial = &conn->initial_mem;
conn->secure = &conn->secure_mem;

/* Allocate the fixed-size stuffers */
blob = (struct s2n_blob) {0};
PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->alert_in_data, S2N_ALERT_LENGTH));
Expand All @@ -122,19 +95,10 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode)
PTR_GUARD_POSIX(s2n_blob_init(&blob, conn->ticket_ext_data, S2N_TLS12_TICKET_SIZE_IN_BYTES));
PTR_GUARD_POSIX(s2n_stuffer_init(&conn->client_ticket_to_decrypt, &blob));

/* Allocate long term key memory */
PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->secure->client_key));
PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->secure->server_key));
PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->initial->client_key));
PTR_GUARD_POSIX(s2n_session_key_alloc(&conn->initial->server_key));

/* Allocate long term hash and HMAC memory */
PTR_GUARD_RESULT(s2n_prf_new(conn));
PTR_GUARD_RESULT(s2n_handshake_hashes_new(&conn->handshake.hashes));

PTR_GUARD_POSIX(s2n_connection_new_hmacs(conn));
PTR_GUARD_POSIX(s2n_connection_init_hmacs(conn));

/* Initialize the growable stuffers. Zero length at first, but the resize
* in _wipe will fix that
*/
Expand All @@ -156,30 +120,12 @@ struct s2n_connection *s2n_connection_new(s2n_mode mode)
return conn;
}

static int s2n_connection_free_keys(struct s2n_connection *conn)
{
POSIX_GUARD(s2n_session_key_free(&conn->secure->client_key));
POSIX_GUARD(s2n_session_key_free(&conn->secure->server_key));
POSIX_GUARD(s2n_session_key_free(&conn->initial->client_key));
POSIX_GUARD(s2n_session_key_free(&conn->initial->server_key));

return 0;
}

static int s2n_connection_zero(struct s2n_connection *conn, int mode, struct s2n_config *config)
{
/* Zero the whole connection structure */
POSIX_CHECKED_MEMSET(conn, 0, sizeof(struct s2n_connection));

/* TODO: swap this to a real heap allocation */
conn->initial = &conn->initial_mem;
conn->secure = &conn->secure_mem;

conn->mode = mode;
conn->initial->cipher_suite = &s2n_null_cipher_suite;
conn->secure->cipher_suite = &s2n_null_cipher_suite;
conn->server = conn->initial;
conn->client = conn->initial;
conn->max_outgoing_fragment_length = S2N_DEFAULT_FRAGMENT_LENGTH;
conn->handshake.end_of_messages = APPLICATION_DATA;
s2n_connection_set_config(conn, config);
Expand All @@ -202,16 +148,6 @@ S2N_RESULT s2n_connection_wipe_all_keyshares(struct s2n_connection *conn)

static int s2n_connection_wipe_keys(struct s2n_connection *conn)
{
/* Destroy any keys - we call destroy on the object as that is where
* keys are allocated. */
if (conn->secure->cipher_suite
&& conn->secure->cipher_suite->record_alg
&& conn->secure->cipher_suite->record_alg->cipher
&& conn->secure->cipher_suite->record_alg->cipher->destroy_key) {
POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->destroy_key(&conn->secure->client_key));
POSIX_GUARD(conn->secure->cipher_suite->record_alg->cipher->destroy_key(&conn->secure->server_key));
}

/* Free any server key received (we may not have completed a
* handshake, so this may not have been free'd yet) */
POSIX_GUARD(s2n_pkey_free(&conn->handshake_params.server_public_key));
Expand All @@ -228,17 +164,6 @@ static int s2n_connection_wipe_keys(struct s2n_connection *conn)
return 0;
}

static int s2n_connection_reset_hmacs(struct s2n_connection *conn)
{
/* Reset all of the Connection's HMAC states */
POSIX_GUARD(s2n_hmac_reset(&conn->initial->client_record_mac));
POSIX_GUARD(s2n_hmac_reset(&conn->initial->server_record_mac));
POSIX_GUARD(s2n_hmac_reset(&conn->secure->client_record_mac));
POSIX_GUARD(s2n_hmac_reset(&conn->secure->server_record_mac));

return 0;
}

static int s2n_connection_free_managed_recv_io(struct s2n_connection *conn)
{
POSIX_ENSURE_REF(conn);
Expand Down Expand Up @@ -285,17 +210,6 @@ static int s2n_connection_wipe_io(struct s2n_connection *conn)
return 0;
}

static int s2n_connection_free_hmacs(struct s2n_connection *conn)
{
/* Free all of the Connection's HMAC states */
POSIX_GUARD(s2n_hmac_free(&conn->initial->client_record_mac));
POSIX_GUARD(s2n_hmac_free(&conn->initial->server_record_mac));
POSIX_GUARD(s2n_hmac_free(&conn->secure->client_record_mac));
POSIX_GUARD(s2n_hmac_free(&conn->secure->server_record_mac));

return 0;
}

static uint8_t s2n_default_verify_host(const char *host_name, size_t len, void *data)
{
/* if present, match server_name of the connection using rules
Expand Down Expand Up @@ -341,15 +255,11 @@ S2N_CLEANUP_RESULT s2n_connection_ptr_free(struct s2n_connection **conn)
int s2n_connection_free(struct s2n_connection *conn)
{
POSIX_GUARD(s2n_connection_wipe_keys(conn));
POSIX_GUARD(s2n_connection_free_keys(conn));
POSIX_GUARD_RESULT(s2n_psk_parameters_wipe(&conn->psk_params));

POSIX_GUARD_RESULT(s2n_prf_free(conn));
POSIX_GUARD_RESULT(s2n_handshake_hashes_free(&conn->handshake.hashes));

POSIX_GUARD(s2n_connection_reset_hmacs(conn));
POSIX_GUARD(s2n_connection_free_hmacs(conn));

POSIX_GUARD(s2n_connection_free_managed_io(conn));

POSIX_GUARD(s2n_free(&conn->client_ticket));
Expand All @@ -365,6 +275,8 @@ int s2n_connection_free(struct s2n_connection *conn)
POSIX_GUARD(s2n_client_hello_free(&conn->client_hello));
POSIX_GUARD(s2n_free(&conn->application_protocols_overridden));
POSIX_GUARD(s2n_free(&conn->cookie));
POSIX_GUARD_RESULT(s2n_crypto_parameters_free(&conn->initial));
POSIX_GUARD_RESULT(s2n_crypto_parameters_free(&conn->secure));
POSIX_GUARD(s2n_free_object((uint8_t **)&conn, sizeof(struct s2n_connection)));

return 0;
Expand Down Expand Up @@ -533,13 +445,6 @@ int s2n_connection_wipe(struct s2n_connection *conn)
struct s2n_stuffer header_in = {0};
struct s2n_stuffer in = {0};
struct s2n_stuffer out = {0};
/* Session keys will be wiped. Preserve structs to avoid reallocation */
struct s2n_session_key initial_client_key = {0};
struct s2n_session_key initial_server_key = {0};
struct s2n_session_key secure_client_key = {0};
struct s2n_session_key secure_server_key = {0};
/* Parts of the hmac states will be wiped. Preserve structs to avoid reallocation */
struct s2n_connection_hmac_handles hmac_handles = {0};

/* Some required structures might have been freed to conserve memory between handshakes.
* Restore them.
Expand All @@ -554,10 +459,21 @@ int s2n_connection_wipe(struct s2n_connection *conn)
}
POSIX_GUARD_RESULT(s2n_prf_wipe(conn));
struct s2n_prf_working_space *prf_workspace = conn->prf_space;
if (!conn->initial) {
POSIX_GUARD_RESULT(s2n_crypto_parameters_new(&conn->initial));
} else {
POSIX_GUARD_RESULT(s2n_crypto_parameters_wipe(conn->initial));
}
struct s2n_crypto_parameters *initial = conn->initial;
if (!conn->secure) {
POSIX_GUARD_RESULT(s2n_crypto_parameters_new(&conn->secure));
} else {
POSIX_GUARD_RESULT(s2n_crypto_parameters_wipe(conn->secure));
}
struct s2n_crypto_parameters *secure = conn->secure;

/* Wipe all of the sensitive stuff */
POSIX_GUARD(s2n_connection_wipe_keys(conn));
POSIX_GUARD(s2n_connection_reset_hmacs(conn));
POSIX_GUARD(s2n_stuffer_wipe(&conn->alert_in));
POSIX_GUARD(s2n_stuffer_wipe(&conn->reader_alert_out));
POSIX_GUARD(s2n_stuffer_wipe(&conn->writer_alert_out));
Expand Down Expand Up @@ -611,11 +527,6 @@ int s2n_connection_wipe(struct s2n_connection *conn)
POSIX_CHECKED_MEMCPY(&header_in, &conn->header_in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&in, &conn->in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&out, &conn->out, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&initial_client_key, &conn->initial->client_key, sizeof(struct s2n_session_key));
POSIX_CHECKED_MEMCPY(&initial_server_key, &conn->initial->server_key, sizeof(struct s2n_session_key));
POSIX_CHECKED_MEMCPY(&secure_client_key, &conn->secure->client_key, sizeof(struct s2n_session_key));
POSIX_CHECKED_MEMCPY(&secure_server_key, &conn->secure->server_key, sizeof(struct s2n_session_key));
POSIX_GUARD(s2n_connection_save_hmac_state(&hmac_handles, conn));
#if S2N_GCC_VERSION_AT_LEAST(4,6,0)
#pragma GCC diagnostic pop
#endif
Expand All @@ -630,16 +541,13 @@ int s2n_connection_wipe(struct s2n_connection *conn)
POSIX_CHECKED_MEMCPY(&conn->header_in, &header_in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&conn->in, &in, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&conn->out, &out, sizeof(struct s2n_stuffer));
POSIX_CHECKED_MEMCPY(&conn->initial->client_key, &initial_client_key, sizeof(struct s2n_session_key));
POSIX_CHECKED_MEMCPY(&conn->initial->server_key, &initial_server_key, sizeof(struct s2n_session_key));
POSIX_CHECKED_MEMCPY(&conn->secure->client_key, &secure_client_key, sizeof(struct s2n_session_key));
POSIX_CHECKED_MEMCPY(&conn->secure->server_key, &secure_server_key, sizeof(struct s2n_session_key));
POSIX_GUARD(s2n_connection_restore_hmac_state(conn, &hmac_handles));

conn->handshake.hashes = handshake_hashes;
conn->prf_space = prf_workspace;

/* Re-initialize hash and hmac states */
POSIX_GUARD(s2n_connection_init_hmacs(conn));
conn->initial = initial;
conn->secure = secure;
conn->client = conn->initial;
conn->server = conn->initial;

POSIX_GUARD_RESULT(s2n_psk_parameters_init(&conn->psk_params));
conn->server_keying_material_lifetime = ONE_WEEK_IN_SEC;
Expand Down
2 changes: 0 additions & 2 deletions tls/s2n_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ struct s2n_connection {
/* Our crypto parameters */
struct s2n_crypto_parameters *initial;
struct s2n_crypto_parameters *secure;
struct s2n_crypto_parameters initial_mem;
struct s2n_crypto_parameters secure_mem;
union s2n_secrets secrets;

/* Which set is the client/server actually using? */
Expand Down
44 changes: 0 additions & 44 deletions tls/s2n_connection_evp_digests.c

This file was deleted.

34 changes: 0 additions & 34 deletions tls/s2n_connection_evp_digests.h

This file was deleted.

Loading

0 comments on commit 0754e5c

Please sign in to comment.