aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/sctp/sctp_output.c
diff options
context:
space:
mode:
authorMarco Varlese <marco.varlese@suse.com>2018-01-31 11:00:01 +0100
committerFlorin Coras <florin.coras@gmail.com>2018-02-01 23:45:03 +0000
commit91389ac2c28ae10f2b7f766e4dfe7a7fd96dc5e0 (patch)
tree8a0286cca7960df4f1365f7e20a9a34ced835c4c /src/vnet/sctp/sctp_output.c
parent75e7d1301475d49311d14e202936c62df0c07d10 (diff)
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 <marco.varlese@suse.com>
Diffstat (limited to 'src/vnet/sctp/sctp_output.c')
-rw-r--r--src/vnet/sctp/sctp_output.c38
1 files changed, 34 insertions, 4 deletions
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 <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_debug.h>
#include <vppinfra/random.h>
+#include <openssl/hmac.h>
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);