From 91389ac2c28ae10f2b7f766e4dfe7a7fd96dc5e0 Mon Sep 17 00:00:00 2001 From: Marco Varlese Date: Wed, 31 Jan 2018 11:00:01 +0100 Subject: Out-of-order data chunks handling and more This patch addresses the need to handle out-of-order data chunks received by a peer. To do that effectively, we had to add the handling of data chunks flags (E/B/U bit) to understand whether the stream is fragmenting user-message data and in that case if a fragment is the FIRST/MIDDLE/LAST one of a transmission. The same patch also addresses the security requirement to have a HMAC calculated and incorporated in the INIT_ACK and COOKIE_ECHO chunks. The algorithm used is the HMAC-SHA1. Change-Id: Ib6a9a80492e2aafe5c8480d6e02da895efe9f90b Signed-off-by: Marco Varlese --- src/vnet/sctp/sctp_output.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'src/vnet/sctp/sctp_output.c') diff --git a/src/vnet/sctp/sctp_output.c b/src/vnet/sctp/sctp_output.c index 7b22cc59ac4..3d870ff5bd4 100644 --- a/src/vnet/sctp/sctp_output.c +++ b/src/vnet/sctp/sctp_output.c @@ -15,6 +15,7 @@ #include #include #include +#include vlib_node_registration_t sctp4_output_node; vlib_node_registration_t sctp6_output_node; @@ -494,10 +495,35 @@ sctp_prepare_init_chunk (sctp_connection_t * sctp_conn, vlib_buffer_t * b) init_chunk->sctp_hdr.dst_port); } -u64 -sctp_compute_mac () +void +sctp_compute_mac (sctp_connection_t * sctp_conn, + sctp_state_cookie_param_t * state_cookie) { - return 0x0; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + HMAC_CTX *ctx; +#else + HMAC_CTX ctx; + const EVP_MD *md = EVP_sha1 (); +#endif + unsigned int len = 0; + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + ctx = HMAC_CTX_new (); + HMAC_Init_ex (&ctx, &state_cookie->creation_time, + sizeof (state_cookie->creation_time), md, NULL); + HMAC_Update (ctx, (const unsigned char *) &sctp_conn, sizeof (sctp_conn)); + HMAC_Final (ctx, state_cookie->mac, &len); +#else + HMAC_CTX_init (&ctx); + HMAC_Init_ex (&ctx, &state_cookie->creation_time, + sizeof (state_cookie->creation_time), md, NULL); + + HMAC_Update (&ctx, (const unsigned char *) &sctp_conn, sizeof (sctp_conn)); + HMAC_Final (&ctx, state_cookie->mac, &len); + HMAC_CTX_cleanup (&ctx); +#endif + + ENDIANESS_SWAP (state_cookie->mac); } void @@ -626,7 +652,8 @@ sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, vlib_buffer_t * b, state_cookie_param->creation_time = clib_host_to_net_u32 (sctp_time_now ()); state_cookie_param->cookie_lifespan = clib_host_to_net_u32 (SCTP_VALID_COOKIE_LIFE); - state_cookie_param->mac = clib_host_to_net_u64 (sctp_compute_mac ()); + + sctp_compute_mac (sctp_conn, state_cookie_param); pointer_offset += sizeof (sctp_state_cookie_param_t); @@ -1068,6 +1095,9 @@ sctp_push_hdr_i (sctp_connection_t * sctp_conn, vlib_buffer_t * b, vnet_sctp_set_chunk_type (&data_chunk->chunk_hdr, DATA); vnet_sctp_set_chunk_length (&data_chunk->chunk_hdr, chunk_length); + vnet_sctp_set_bbit (&data_chunk->chunk_hdr); + vnet_sctp_set_ebit (&data_chunk->chunk_hdr); + SCTP_ADV_DBG_OUTPUT ("POINTER_WITH_DATA = %p, DATA_OFFSET = %u", b->data, b->current_data); -- cgit 1.2.3-korg