summaryrefslogtreecommitdiff
path: root/include/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/sctp')
-rw-r--r--include/net/sctp/auth.h128
-rw-r--r--include/net/sctp/command.h1
-rw-r--r--include/net/sctp/constants.h53
-rw-r--r--include/net/sctp/sctp.h17
-rw-r--r--include/net/sctp/sm.h8
-rw-r--r--include/net/sctp/structs.h100
-rw-r--r--include/net/sctp/ulpevent.h4
-rw-r--r--include/net/sctp/ulpqueue.h1
-rw-r--r--include/net/sctp/user.h90
9 files changed, 387 insertions, 15 deletions
diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h
new file mode 100644
index 000000000000..4945954a16af
--- /dev/null
+++ b/include/net/sctp/auth.h
@@ -0,0 +1,128 @@
+/* SCTP kernel reference Implementation
+ * (C) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ *
+ * This file is part of the SCTP kernel reference Implementation
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ * lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ * http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ * Vlad Yasevich <vladislav.yasevich@hp.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+#ifndef __sctp_auth_h__
+#define __sctp_auth_h__
+
+#include <linux/list.h>
+#include <linux/crypto.h>
+
+struct sctp_endpoint;
+struct sctp_association;
+struct sctp_authkey;
+struct sctp_hmacalgo;
+
+/*
+ * Define a generic struct that will hold all the info
+ * necessary for an HMAC transform
+ */
+struct sctp_hmac {
+ __u16 hmac_id; /* one of the above ids */
+ char *hmac_name; /* name for loading */
+ __u16 hmac_len; /* length of the signature */
+};
+
+/* This is generic structure that containst authentication bytes used
+ * as keying material. It's a what is referred to as byte-vector all
+ * over SCTP-AUTH
+ */
+struct sctp_auth_bytes {
+ atomic_t refcnt;
+ __u32 len;
+ __u8 data[];
+};
+
+/* Definition for a shared key, weather endpoint or association */
+struct sctp_shared_key {
+ struct list_head key_list;
+ __u16 key_id;
+ struct sctp_auth_bytes *key;
+};
+
+#define key_for_each(__key, __list_head) \
+ list_for_each_entry(__key, __list_head, key_list)
+
+#define key_for_each_safe(__key, __tmp, __list_head) \
+ list_for_each_entry_safe(__key, __tmp, __list_head, key_list)
+
+static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key)
+{
+ if (!key)
+ return;
+
+ atomic_inc(&key->refcnt);
+}
+
+void sctp_auth_key_put(struct sctp_auth_bytes *key);
+struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp);
+void sctp_auth_shkey_free(struct sctp_shared_key *sh_key);
+void sctp_auth_destroy_keys(struct list_head *keys);
+int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp);
+struct sctp_shared_key *sctp_auth_get_shkey(
+ const struct sctp_association *asoc,
+ __u16 key_id);
+int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep,
+ struct sctp_association *asoc,
+ gfp_t gfp);
+int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp);
+void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[]);
+struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id);
+struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc);
+void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
+ struct sctp_hmac_algo_param *hmacs);
+int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
+ __u16 hmac_id);
+int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
+int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
+void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
+ struct sk_buff *skb,
+ struct sctp_auth_chunk *auth, gfp_t gfp);
+
+/* API Helpers */
+int sctp_auth_ep_add_chunkid(struct sctp_endpoint *ep, __u8 chunk_id);
+int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
+ struct sctp_hmacalgo *hmacs);
+int sctp_auth_set_key(struct sctp_endpoint *ep,
+ struct sctp_association *asoc,
+ struct sctp_authkey *auth_key);
+int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+ struct sctp_association *asoc,
+ __u16 key_id);
+int sctp_auth_del_key_id(struct sctp_endpoint *ep,
+ struct sctp_association *asoc,
+ __u16 key_id);
+
+#endif
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index f56c8d695a82..b8733364557f 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -102,6 +102,7 @@ typedef enum {
SCTP_CMD_SET_SK_ERR, /* Set sk_err */
SCTP_CMD_ASSOC_CHANGE, /* generate and send assoc_change event */
SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
+ SCTP_CMD_ASSOC_SHKEY, /* generate the association shared keys */
SCTP_CMD_LAST
} sctp_verb_t;
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index bb37724495a5..da8354e8e33c 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -64,12 +64,18 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
#define SCTP_CID_MAX SCTP_CID_ASCONF_ACK
#define SCTP_NUM_BASE_CHUNK_TYPES (SCTP_CID_BASE_MAX + 1)
-#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNKTYPES + 2)
#define SCTP_NUM_ADDIP_CHUNK_TYPES 2
#define SCTP_NUM_PRSCTP_CHUNK_TYPES 1
+#define SCTP_NUM_AUTH_CHUNK_TYPES 1
+
+#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNK_TYPES + \
+ SCTP_NUM_ADDIP_CHUNK_TYPES +\
+ SCTP_NUM_PRSCTP_CHUNK_TYPES +\
+ SCTP_NUM_AUTH_CHUNK_TYPES)
+
/* These are the different flavours of event. */
typedef enum {
@@ -177,7 +183,9 @@ typedef enum {
SCTP_IERROR_NO_DATA,
SCTP_IERROR_BAD_STREAM,
SCTP_IERROR_BAD_PORTS,
-
+ SCTP_IERROR_AUTH_BAD_HMAC,
+ SCTP_IERROR_AUTH_BAD_KEYID,
+ SCTP_IERROR_PROTO_VIOLATION,
} sctp_ierror_t;
@@ -409,4 +417,45 @@ typedef enum {
SCTP_LOWER_CWND_INACTIVE,
} sctp_lower_cwnd_t;
+
+/* SCTP-AUTH Necessary constants */
+
+/* SCTP-AUTH, Section 3.3
+ *
+ * The following Table 2 shows the currently defined values for HMAC
+ * identifiers.
+ *
+ * +-----------------+--------------------------+
+ * | HMAC Identifier | Message Digest Algorithm |
+ * +-----------------+--------------------------+
+ * | 0 | Reserved |
+ * | 1 | SHA-1 defined in [8] |
+ * | 2 | Reserved |
+ * | 3 | SHA-256 defined in [8] |
+ * +-----------------+--------------------------+
+ */
+enum {
+ SCTP_AUTH_HMAC_ID_RESERVED_0,
+ SCTP_AUTH_HMAC_ID_SHA1,
+ SCTP_AUTH_HMAC_ID_RESERVED_2,
+ SCTP_AUTH_HMAC_ID_SHA256
+};
+
+#define SCTP_AUTH_HMAC_ID_MAX SCTP_AUTH_HMAC_ID_SHA256
+#define SCTP_AUTH_NUM_HMACS (SCTP_AUTH_HMAC_ID_SHA256 + 1)
+#define SCTP_SHA1_SIG_SIZE 20
+#define SCTP_SHA256_SIG_SIZE 32
+
+/* SCTP-AUTH, Section 3.2
+ * The chunk types for INIT, INIT-ACK, SHUTDOWN-COMPLETE and AUTH chunks
+ * MUST NOT be listed in the CHUNKS parameter
+ */
+#define SCTP_NUM_NOAUTH_CHUNKS 4
+#define SCTP_AUTH_MAX_CHUNKS (SCTP_NUM_CHUNK_TYPES - SCTP_NUM_NOAUTH_CHUNKS)
+
+/* SCTP-AUTH Section 6.1
+ * The RANDOM parameter MUST contain a 32 byte random number.
+ */
+#define SCTP_AUTH_RANDOM_LENGTH 32
+
#endif /* __sctp_constants_h__ */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 16baef4dab7e..119f5a1ed499 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -123,6 +123,7 @@
* sctp/protocol.c
*/
extern struct sock *sctp_get_ctl_sock(void);
+extern void sctp_local_addr_free(struct rcu_head *head);
extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
sctp_scope_t, gfp_t gfp,
int flags);
@@ -190,6 +191,16 @@ void sctp_assocs_proc_exit(void);
/*
+ * Module global variables
+ */
+
+ /*
+ * sctp/protocol.c
+ */
+extern struct kmem_cache *sctp_chunk_cachep __read_mostly;
+extern struct kmem_cache *sctp_bucket_cachep __read_mostly;
+
+/*
* Section: Macros, externs, and inlines
*/
@@ -330,6 +341,7 @@ extern atomic_t sctp_dbg_objcnt_bind_bucket;
extern atomic_t sctp_dbg_objcnt_addr;
extern atomic_t sctp_dbg_objcnt_ssnmap;
extern atomic_t sctp_dbg_objcnt_datamsg;
+extern atomic_t sctp_dbg_objcnt_keys;
/* Macros to atomically increment/decrement objcnt counters. */
#define SCTP_DBG_OBJCNT_INC(name) \
@@ -458,6 +470,11 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
skb->sk = sk;
skb->destructor = sctp_sock_rfree;
atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
+ /*
+ * This mimics the behavior of
+ * sk_stream_set_owner_r
+ */
+ sk->sk_forward_alloc -= event->rmem_len;
}
/* Tests if the list has one and only one entry. */
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 73cb9943c8a8..bf2f5ed69c15 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -114,7 +114,6 @@ sctp_state_fn_t sctp_sf_do_4_C;
sctp_state_fn_t sctp_sf_eat_data_6_2;
sctp_state_fn_t sctp_sf_eat_data_fast_4_4;
sctp_state_fn_t sctp_sf_eat_sack_6_2;
-sctp_state_fn_t sctp_sf_tabort_8_4_8;
sctp_state_fn_t sctp_sf_operr_notify;
sctp_state_fn_t sctp_sf_t1_init_timer_expire;
sctp_state_fn_t sctp_sf_t1_cookie_timer_expire;
@@ -144,6 +143,7 @@ sctp_state_fn_t sctp_sf_do_asconf_ack;
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
sctp_state_fn_t sctp_sf_eat_fwd_tsn;
sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
+sctp_state_fn_t sctp_sf_eat_auth;
/* Prototypes for primitive event state functions. */
sctp_state_fn_t sctp_sf_do_prm_asoc;
@@ -214,7 +214,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
const struct sctp_chunk *);
struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *,
const struct sctp_chunk *);
-void sctp_init_cause(struct sctp_chunk *, __be16 cause, const void *, size_t);
+void sctp_init_cause(struct sctp_chunk *, __be16 cause, size_t);
struct sctp_chunk *sctp_make_abort(const struct sctp_association *,
const struct sctp_chunk *,
const size_t hint);
@@ -247,6 +247,9 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
int, __be16);
struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
union sctp_addr *addr);
+int sctp_verify_asconf(const struct sctp_association *asoc,
+ struct sctp_paramhdr *param_hdr, void *chunk_end,
+ struct sctp_paramhdr **errp);
struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
struct sctp_chunk *asconf);
int sctp_process_asconf_ack(struct sctp_association *asoc,
@@ -254,6 +257,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
__u32 new_cum_tsn, size_t nstreams,
struct sctp_fwdtsn_skip *skiplist);
+struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc);
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index ee4559b11302..ef892e00c833 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -64,6 +64,7 @@
#include <linux/skbuff.h> /* We need sk_buff_head. */
#include <linux/workqueue.h> /* We need tq_struct. */
#include <linux/sctp.h> /* We need sctp* header structs. */
+#include <net/sctp/auth.h> /* We need auth specific structs */
/* A convenience structure for handling sockaddr structures.
* We should wean ourselves off this.
@@ -196,8 +197,6 @@ extern struct sctp_globals {
/* This is the sctp port control hash. */
int port_hashsize;
- int port_rover;
- spinlock_t port_alloc_lock; /* Protects port_rover. */
struct sctp_bind_hashbucket *port_hashtable;
/* This is the global local address list.
@@ -207,12 +206,18 @@ extern struct sctp_globals {
* It is a list of sctp_sockaddr_entry.
*/
struct list_head local_addr_list;
+
+ /* Lock that protects the local_addr_list writers */
+ spinlock_t addr_list_lock;
/* Flag to indicate if addip is enabled. */
int addip_enable;
/* Flag to indicate if PR-SCTP is enabled. */
int prsctp_enable;
+
+ /* Flag to idicate if SCTP-AUTH is enabled */
+ int auth_enable;
} sctp_globals;
#define sctp_rto_initial (sctp_globals.rto_initial)
@@ -242,8 +247,10 @@ extern struct sctp_globals {
#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
#define sctp_port_hashtable (sctp_globals.port_hashtable)
#define sctp_local_addr_list (sctp_globals.local_addr_list)
+#define sctp_local_addr_lock (sctp_globals.addr_list_lock)
#define sctp_addip_enable (sctp_globals.addip_enable)
#define sctp_prsctp_enable (sctp_globals.prsctp_enable)
+#define sctp_auth_enable (sctp_globals.auth_enable)
/* SCTP Socket type: UDP or TCP style. */
typedef enum {
@@ -393,6 +400,9 @@ struct sctp_cookie {
__u32 adaptation_ind;
+ __u8 auth_random[sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH];
+ __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS + 2];
+ __u8 auth_chunks[sizeof(sctp_paramhdr_t) + SCTP_AUTH_MAX_CHUNKS];
/* This is a shim for my peer's INIT packet, followed by
* a copy of the raw address list of the association.
@@ -417,6 +427,7 @@ struct sctp_signed_cookie {
* internally.
*/
union sctp_addr_param {
+ struct sctp_paramhdr p;
struct sctp_ipv4addr_param v4;
struct sctp_ipv6addr_param v6;
};
@@ -435,6 +446,10 @@ union sctp_params {
struct sctp_ipv6addr_param *v6;
union sctp_addr_param *addr;
struct sctp_adaptation_ind_param *aind;
+ struct sctp_supported_ext_param *ext;
+ struct sctp_random_param *random;
+ struct sctp_chunks_param *chunks;
+ struct sctp_hmac_algo_param *hmac_algo;
};
/* RFC 2960. Section 3.3.5 Heartbeat.
@@ -673,6 +688,7 @@ struct sctp_chunk {
struct sctp_errhdr *err_hdr;
struct sctp_addiphdr *addip_hdr;
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
+ struct sctp_authhdr *auth_hdr;
} subh;
__u8 *chunk_end;
@@ -706,6 +722,13 @@ struct sctp_chunk {
*/
struct sctp_transport *transport;
+ /* SCTP-AUTH: For the special case inbound processing of COOKIE-ECHO
+ * we need save a pointer to the AUTH chunk, since the SCTP-AUTH
+ * spec violates the principle premis that all chunks are processed
+ * in order.
+ */
+ struct sk_buff *auth_chunk;
+
__u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */
__u8 resent; /* Has this chunk ever been retransmitted. */
__u8 has_tsn; /* Does this chunk have a TSN yet? */
@@ -718,6 +741,7 @@ struct sctp_chunk {
__s8 fast_retransmit; /* Is this chunk fast retransmitted? */
__u8 tsn_missing_report; /* Data chunk missing counter. */
__u8 data_accepted; /* At least 1 chunk in this packet accepted */
+ __u8 auth; /* IN: was auth'ed | OUT: needs auth */
};
void sctp_chunk_hold(struct sctp_chunk *);
@@ -736,8 +760,10 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
/* This is a structure for holding either an IPv6 or an IPv4 address. */
struct sctp_sockaddr_entry {
struct list_head list;
+ struct rcu_head rcu;
union sctp_addr a;
__u8 use_as_src;
+ __u8 valid;
};
typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *);
@@ -765,16 +791,25 @@ struct sctp_packet {
*/
struct sctp_transport *transport;
+ /* pointer to the auth chunk for this packet */
+ struct sctp_chunk *auth;
+
/* This packet contains a COOKIE-ECHO chunk. */
- char has_cookie_echo;
+ __u8 has_cookie_echo;
+
+ /* This packet contains a SACK chunk. */
+ __u8 has_sack;
- /* This packet containsa SACK chunk. */
- char has_sack;
+ /* This packet contains an AUTH chunk */
+ __u8 has_auth;
+
+ /* This packet contains at least 1 DATA chunk */
+ __u8 has_data;
/* SCTP cannot fragment this packet. So let ip fragment it. */
- char ipfragok;
+ __u8 ipfragok;
- int malloced;
+ __u8 malloced;
};
struct sctp_packet *sctp_packet_init(struct sctp_packet *,
@@ -1037,6 +1072,7 @@ void sctp_inq_init(struct sctp_inq *);
void sctp_inq_free(struct sctp_inq *);
void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
+struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *);
void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t);
/* This is the structure we use to hold outbound chunks. You push
@@ -1148,7 +1184,9 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
int flags);
int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
__u8 use_as_src, gfp_t gfp);
-int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
+int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
+ void fastcall (*rcu_call)(struct rcu_head *,
+ void (*func)(struct rcu_head *)));
int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
struct sctp_sock *);
union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp,
@@ -1219,9 +1257,6 @@ struct sctp_ep_common {
* bind_addr.address_list is our set of local IP addresses.
*/
struct sctp_bind_addr bind_addr;
-
- /* Protection during address list comparisons. */
- rwlock_t addr_lock;
};
@@ -1284,6 +1319,21 @@ struct sctp_endpoint {
/* rcvbuf acct. policy. */
__u32 rcvbuf_policy;
+
+ /* SCTP AUTH: array of the HMACs that will be allocated
+ * we need this per association so that we don't serialize
+ */
+ struct crypto_hash **auth_hmacs;
+
+ /* SCTP-AUTH: hmacs for the endpoint encoded into parameter */
+ struct sctp_hmac_algo_param *auth_hmacs_list;
+
+ /* SCTP-AUTH: chunks to authenticate encoded into parameter */
+ struct sctp_chunks_param *auth_chunk_list;
+
+ /* SCTP-AUTH: endpoint shared keys */
+ struct list_head endpoint_shared_keys;
+ __u16 active_key_id;
};
/* Recover the outter endpoint structure. */
@@ -1490,6 +1540,8 @@ struct sctp_association {
__u8 hostname_address;/* Peer understands DNS addresses? */
__u8 asconf_capable; /* Does peer support ADDIP? */
__u8 prsctp_capable; /* Can peer do PR-SCTP? */
+ __u8 auth_capable; /* Is peer doing SCTP-AUTH? */
+ __u8 addip_capable; /* Can peer do ADD-IP */
__u32 adaptation_ind; /* Adaptation Code point. */
@@ -1507,6 +1559,14 @@ struct sctp_association {
* Initial TSN Value minus 1
*/
__u32 addip_serial;
+
+ /* SCTP-AUTH: We need to know pears random number, hmac list
+ * and authenticated chunk list. All that is part of the
+ * cookie and these are just pointers to those locations
+ */
+ sctp_random_param_t *peer_random;
+ sctp_chunks_param_t *peer_chunks;
+ sctp_hmac_algo_param_t *peer_hmacs;
} peer;
/* State : A state variable indicating what state the
@@ -1790,6 +1850,24 @@ struct sctp_association {
*/
__u32 addip_serial;
+ /* SCTP AUTH: list of the endpoint shared keys. These
+ * keys are provided out of band by the user applicaton
+ * and can't change during the lifetime of the association
+ */
+ struct list_head endpoint_shared_keys;
+
+ /* SCTP AUTH:
+ * The current generated assocaition shared key (secret)
+ */
+ struct sctp_auth_bytes *asoc_shared_key;
+
+ /* SCTP AUTH: hmac id of the first peer requested algorithm
+ * that we support.
+ */
+ __u16 default_hmac_id;
+
+ __u16 active_key_id;
+
/* Need to send an ECNE Chunk? */
char need_ecne;
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index de88ed5b0ba6..922a151eb93c 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -128,6 +128,10 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
struct sctp_chunk *chunk,
gfp_t gfp);
+struct sctp_ulpevent *sctp_ulpevent_make_authkey(
+ const struct sctp_association *asoc, __u16 key_id,
+ __u32 indication, gfp_t gfp);
+
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
index 39ea3f442b47..cd33270e86dd 100644
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -83,6 +83,7 @@ int sctp_clear_pd(struct sock *sk, struct sctp_association *asoc);
/* Skip over an SSN. */
void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn);
+void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *, __u32);
#endif /* __sctp_ulpqueue_h__ */
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 6d2b57758cca..00848b641f59 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -103,6 +103,21 @@ enum sctp_optname {
#define SCTP_PARTIAL_DELIVERY_POINT SCTP_PARTIAL_DELIVERY_POINT
SCTP_MAX_BURST, /* Set/Get max burst */
#define SCTP_MAX_BURST SCTP_MAX_BURST
+ SCTP_AUTH_CHUNK, /* Set only: add a chunk type to authenticat */
+#define SCTP_AUTH_CHUNK SCTP_AUTH_CHUNK
+ SCTP_HMAC_IDENT,
+#define SCTP_HMAC_IDENT SCTP_HMAC_IDENT
+ SCTP_AUTH_KEY,
+#define SCTP_AUTH_KEY SCTP_AUTH_KEY
+ SCTP_AUTH_ACTIVE_KEY,
+#define SCTP_AUTH_ACTIVE_KEY SCTP_AUTH_ACTIVE_KEY
+ SCTP_AUTH_DELETE_KEY,
+#define SCTP_AUTH_DELETE_KEY SCTP_AUTH_DELETE_KEY
+ SCTP_PEER_AUTH_CHUNKS, /* Read only */
+#define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS
+ SCTP_LOCAL_AUTH_CHUNKS, /* Read only */
+#define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS
+
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
@@ -370,6 +385,19 @@ struct sctp_pdapi_event {
enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, };
+struct sctp_authkey_event {
+ __u16 auth_type;
+ __u16 auth_flags;
+ __u32 auth_length;
+ __u16 auth_keynumber;
+ __u16 auth_altkeynumber;
+ __u32 auth_indication;
+ sctp_assoc_t auth_assoc_id;
+};
+
+enum { SCTP_AUTH_NEWKEY = 0, };
+
+
/*
* Described in Section 7.3
* Ancillary Data and Notification Interest Options
@@ -405,6 +433,7 @@ union sctp_notification {
struct sctp_shutdown_event sn_shutdown_event;
struct sctp_adaptation_event sn_adaptation_event;
struct sctp_pdapi_event sn_pdapi_event;
+ struct sctp_authkey_event sn_authkey_event;
};
/* Section 5.3.1
@@ -421,6 +450,7 @@ enum sctp_sn_type {
SCTP_SHUTDOWN_EVENT,
SCTP_PARTIAL_DELIVERY_EVENT,
SCTP_ADAPTATION_INDICATION,
+ SCTP_AUTHENTICATION_EVENT,
};
/* Notification error codes used to fill up the error fields in some
@@ -539,6 +569,54 @@ struct sctp_paddrparams {
__u32 spp_flags;
} __attribute__((packed, aligned(4)));
+/*
+ * 7.1.18. Add a chunk that must be authenticated (SCTP_AUTH_CHUNK)
+ *
+ * This set option adds a chunk type that the user is requesting to be
+ * received only in an authenticated way. Changes to the list of chunks
+ * will only effect future associations on the socket.
+ */
+struct sctp_authchunk {
+ __u8 sauth_chunk;
+};
+
+/*
+ * 7.1.19. Get or set the list of supported HMAC Identifiers (SCTP_HMAC_IDENT)
+ *
+ * This option gets or sets the list of HMAC algorithms that the local
+ * endpoint requires the peer to use.
+*/
+struct sctp_hmacalgo {
+ __u16 shmac_num_idents;
+ __u16 shmac_idents[];
+};
+
+/*
+ * 7.1.20. Set a shared key (SCTP_AUTH_KEY)
+ *
+ * This option will set a shared secret key which is used to build an
+ * association shared key.
+ */
+struct sctp_authkey {
+ sctp_assoc_t sca_assoc_id;
+ __u16 sca_keynumber;
+ __u16 sca_keylen;
+ __u8 sca_key[];
+};
+
+/*
+ * 7.1.21. Get or set the active shared key (SCTP_AUTH_ACTIVE_KEY)
+ *
+ * This option will get or set the active shared key to be used to build
+ * the association shared key.
+ */
+
+struct sctp_authkeyid {
+ sctp_assoc_t scact_assoc_id;
+ __u16 scact_keynumber;
+};
+
+
/* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
*
* This options will get or set the delayed ack timer. The time is set
@@ -608,6 +686,18 @@ struct sctp_status {
};
/*
+ * 7.2.3. Get the list of chunks the peer requires to be authenticated
+ * (SCTP_PEER_AUTH_CHUNKS)
+ *
+ * This option gets a list of chunks for a specified association that
+ * the peer requires to be received authenticated only.
+ */
+struct sctp_authchunks {
+ sctp_assoc_t gauth_assoc_id;
+ uint8_t gauth_chunks[];
+};
+
+/*
* 8.3, 8.5 get all peer/local addresses in an association.
* This parameter struct is used by SCTP_GET_PEER_ADDRS and
* SCTP_GET_LOCAL_ADDRS socket options used internally to implement