Skip to content

Commit

Permalink
[SCTP]: Implement SCTP-AUTH internals
Browse files Browse the repository at this point in the history
This patch implements the internals operations of the AUTH, such as
key computation and storage.  It also adds necessary variables to
the SCTP data structures.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vlad Yasevich authored and David S. Miller committed Oct 10, 2007
1 parent f7b0e93 commit 1f48564
Show file tree
Hide file tree
Showing 7 changed files with 976 additions and 7 deletions.
112 changes: 112 additions & 0 deletions include/net/sctp/auth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* 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;

/*
* 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);
#endif
49 changes: 48 additions & 1 deletion include/net/sctp/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -409,4 +415,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__ */
1 change: 1 addition & 0 deletions include/net/sctp/sctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,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) \
Expand Down
71 changes: 66 additions & 5 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -216,6 +217,9 @@ extern struct sctp_globals {

/* 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)
Expand Down Expand Up @@ -248,6 +252,7 @@ extern struct sctp_globals {
#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 {
Expand Down Expand Up @@ -397,6 +402,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.
Expand Down Expand Up @@ -441,6 +449,9 @@ union sctp_params {
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.
Expand Down Expand Up @@ -679,6 +690,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;
Expand Down Expand Up @@ -724,6 +736,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 *);
Expand Down Expand Up @@ -773,16 +786,22 @@ 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;

/* 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 *,
Expand Down Expand Up @@ -1291,6 +1310,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. */
Expand Down Expand Up @@ -1497,6 +1531,7 @@ 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? */

__u32 adaptation_ind; /* Adaptation Code point. */

Expand All @@ -1514,6 +1549,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
Expand Down Expand Up @@ -1797,6 +1840,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;

Expand Down
3 changes: 2 additions & 1 deletion net/sctp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
transport.o chunk.o sm_make_chunk.o ulpevent.o \
inqueue.o outqueue.o ulpqueue.o command.o \
tsnmap.o bind_addr.o socket.o primitive.o \
output.o input.o debug.o ssnmap.o proc.o crc32c.o
output.o input.o debug.o ssnmap.o proc.o crc32c.o \
auth.o

sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
sctp-$(CONFIG_SYSCTL) += sysctl.o
Expand Down
Loading

0 comments on commit 1f48564

Please sign in to comment.