aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2012-10-24 05:20:03 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-26 02:22:18 -0400
commit3c68198e75111a905ac2412be12bf7b29099729b (patch)
tree109b39430631746fd4266d5fdbf8351c6c2e20d1 /net/sctp
parent342567ccf088a6c4777ef352f559fe46aaeb047e (diff)
sctp: Make hmac algorithm selection for cookie generation dynamic
Currently sctp allows for the optional use of md5 of sha1 hmac algorithms to generate cookie values when establishing new connections via two build time config options. Theres no real reason to make this a static selection. We can add a sysctl that allows for the dynamic selection of these algorithms at run time, with the default value determined by the corresponding crypto library availability. This comes in handy when, for example running a system in FIPS mode, where use of md5 is disallowed, but SHA1 is permitted. Note: This new sysctl has no corresponding socket option to select the cookie hmac algorithm. I chose not to implement that intentionally, as RFC 6458 contains no option for this value, and I opted not to pollute the socket option namespace. Change notes: v2) * Updated subject to have the proper sctp prefix as per Dave M. * Replaced deafult selection options with new options that allow developers to explicitly select available hmac algs at build time as per suggestion by Vlad Y. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> CC: Vlad Yasevich <vyasevich@gmail.com> CC: "David S. Miller" <davem@davemloft.net> CC: netdev@vger.kernel.org Acked-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/Kconfig39
-rw-r--r--net/sctp/protocol.c9
-rw-r--r--net/sctp/socket.c11
-rw-r--r--net/sctp/sysctl.c59
4 files changed, 88 insertions, 30 deletions
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
index 126b014eb79b..a9edd2e205f4 100644
--- a/net/sctp/Kconfig
+++ b/net/sctp/Kconfig
@@ -9,7 +9,6 @@ menuconfig IP_SCTP
9 select CRYPTO 9 select CRYPTO
10 select CRYPTO_HMAC 10 select CRYPTO_HMAC
11 select CRYPTO_SHA1 11 select CRYPTO_SHA1
12 select CRYPTO_MD5 if SCTP_HMAC_MD5
13 select LIBCRC32C 12 select LIBCRC32C
14 ---help--- 13 ---help---
15 Stream Control Transmission Protocol 14 Stream Control Transmission Protocol
@@ -68,33 +67,21 @@ config SCTP_DBG_OBJCNT
68 67
69 If unsure, say N 68 If unsure, say N
70 69
71choice 70config SCTP_COOKIE_HMAC_MD5
72 prompt "SCTP: Cookie HMAC Algorithm" 71 bool "Enable optional MD5 hmac cookie generation"
73 default SCTP_HMAC_MD5
74 help 72 help
75 HMAC algorithm to be used during association initialization. It 73 Enable optional MD5 hmac based SCTP cookie generation
76 is strongly recommended to use HMAC-SHA1 or HMAC-MD5. See 74 default y
77 configuration for Cryptographic API and enable those algorithms 75 select CRYPTO_HMAC if SCTP_COOKIE_HMAC_MD5
78 to make usable by SCTP. 76 select CRYPTO_MD5 if SCTP_COOKIE_HMAC_MD5
79 77
80config SCTP_HMAC_NONE 78config SCTP_COOKIE_HMAC_SHA1
81 bool "None" 79 bool "Enable optional SHA1 hmac cookie generation"
82 help
83 Choosing this disables the use of an HMAC during association
84 establishment. It is advised to use either HMAC-MD5 or HMAC-SHA1.
85
86config SCTP_HMAC_SHA1
87 bool "HMAC-SHA1"
88 help
89 Enable the use of HMAC-SHA1 during association establishment. It
90 is advised to use either HMAC-MD5 or HMAC-SHA1.
91
92config SCTP_HMAC_MD5
93 bool "HMAC-MD5"
94 help 80 help
95 Enable the use of HMAC-MD5 during association establishment. It is 81 Enable optional SHA1 hmac based SCTP cookie generation
96 advised to use either HMAC-MD5 or HMAC-SHA1. 82 default y
83 select CRYPTO_HMAC if SCTP_COOKIE_HMAC_SHA1
84 select CRYPTO_SHA1 if SCTP_COOKIE_HMAC_SHA1
97 85
98endchoice
99 86
100endif # IP_SCTP 87endif # IP_SCTP
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 2d518425d598..456bc3dbdd51 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1190,6 +1190,15 @@ static int sctp_net_init(struct net *net)
1190 /* Whether Cookie Preservative is enabled(1) or not(0) */ 1190 /* Whether Cookie Preservative is enabled(1) or not(0) */
1191 net->sctp.cookie_preserve_enable = 1; 1191 net->sctp.cookie_preserve_enable = 1;
1192 1192
1193 /* Default sctp sockets to use md5 as their hmac alg */
1194#if defined (CONFIG_CRYPTO_MD5)
1195 net->sctp.sctp_hmac_alg = "md5";
1196#elif defined (CONFIG_CRYPTO_SHA1)
1197 net->sctp.sctp_hmac_alg = "sha1";
1198#else
1199 net->sctp.sctp_hmac_alg = NULL;
1200#endif
1201
1193 /* Max.Burst - 4 */ 1202 /* Max.Burst - 4 */
1194 net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST; 1203 net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST;
1195 1204
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 59d16ea927f0..fa81bdee00a5 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -110,7 +110,6 @@ static int sctp_do_bind(struct sock *, union sctp_addr *, int);
110static int sctp_autobind(struct sock *sk); 110static int sctp_autobind(struct sock *sk);
111static void sctp_sock_migrate(struct sock *, struct sock *, 111static void sctp_sock_migrate(struct sock *, struct sock *,
112 struct sctp_association *, sctp_socket_type_t); 112 struct sctp_association *, sctp_socket_type_t);
113static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
114 113
115extern struct kmem_cache *sctp_bucket_cachep; 114extern struct kmem_cache *sctp_bucket_cachep;
116extern long sysctl_sctp_mem[3]; 115extern long sysctl_sctp_mem[3];
@@ -3890,6 +3889,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3890 sp->default_rcv_context = 0; 3889 sp->default_rcv_context = 0;
3891 sp->max_burst = net->sctp.max_burst; 3890 sp->max_burst = net->sctp.max_burst;
3892 3891
3892 sp->sctp_hmac_alg = net->sctp.sctp_hmac_alg;
3893
3893 /* Initialize default setup parameters. These parameters 3894 /* Initialize default setup parameters. These parameters
3894 * can be modified with the SCTP_INITMSG socket option or 3895 * can be modified with the SCTP_INITMSG socket option or
3895 * overridden by the SCTP_INIT CMSG. 3896 * overridden by the SCTP_INIT CMSG.
@@ -5981,13 +5982,15 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
5981 struct sctp_sock *sp = sctp_sk(sk); 5982 struct sctp_sock *sp = sctp_sk(sk);
5982 struct sctp_endpoint *ep = sp->ep; 5983 struct sctp_endpoint *ep = sp->ep;
5983 struct crypto_hash *tfm = NULL; 5984 struct crypto_hash *tfm = NULL;
5985 char alg[32];
5984 5986
5985 /* Allocate HMAC for generating cookie. */ 5987 /* Allocate HMAC for generating cookie. */
5986 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { 5988 if (!sp->hmac && sp->sctp_hmac_alg) {
5987 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); 5989 sprintf(alg, "hmac(%s)", sp->sctp_hmac_alg);
5990 tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC);
5988 if (IS_ERR(tfm)) { 5991 if (IS_ERR(tfm)) {
5989 net_info_ratelimited("failed to load transform for %s: %ld\n", 5992 net_info_ratelimited("failed to load transform for %s: %ld\n",
5990 sctp_hmac_alg, PTR_ERR(tfm)); 5993 sp->sctp_hmac_alg, PTR_ERR(tfm));
5991 return -ENOSYS; 5994 return -ENOSYS;
5992 } 5995 }
5993 sctp_sk(sk)->hmac = tfm; 5996 sctp_sk(sk)->hmac = tfm;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 70e3ba5cb50b..043889ac86c0 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -62,6 +62,11 @@ extern long sysctl_sctp_mem[3];
62extern int sysctl_sctp_rmem[3]; 62extern int sysctl_sctp_rmem[3];
63extern int sysctl_sctp_wmem[3]; 63extern int sysctl_sctp_wmem[3];
64 64
65static int proc_sctp_do_hmac_alg(ctl_table *ctl,
66 int write,
67 void __user *buffer, size_t *lenp,
68
69 loff_t *ppos);
65static ctl_table sctp_table[] = { 70static ctl_table sctp_table[] = {
66 { 71 {
67 .procname = "sctp_mem", 72 .procname = "sctp_mem",
@@ -147,6 +152,12 @@ static ctl_table sctp_net_table[] = {
147 .proc_handler = proc_dointvec, 152 .proc_handler = proc_dointvec,
148 }, 153 },
149 { 154 {
155 .procname = "cookie_hmac_alg",
156 .maxlen = 8,
157 .mode = 0644,
158 .proc_handler = proc_sctp_do_hmac_alg,
159 },
160 {
150 .procname = "valid_cookie_life", 161 .procname = "valid_cookie_life",
151 .data = &init_net.sctp.valid_cookie_life, 162 .data = &init_net.sctp.valid_cookie_life,
152 .maxlen = sizeof(unsigned int), 163 .maxlen = sizeof(unsigned int),
@@ -289,6 +300,54 @@ static ctl_table sctp_net_table[] = {
289 { /* sentinel */ } 300 { /* sentinel */ }
290}; 301};
291 302
303static int proc_sctp_do_hmac_alg(ctl_table *ctl,
304 int write,
305 void __user *buffer, size_t *lenp,
306 loff_t *ppos)
307{
308 struct net *net = current->nsproxy->net_ns;
309 char tmp[8];
310 ctl_table tbl;
311 int ret;
312 int changed = 0;
313 char *none = "none";
314
315 memset(&tbl, 0, sizeof(struct ctl_table));
316
317 if (write) {
318 tbl.data = tmp;
319 tbl.maxlen = 8;
320 } else {
321 tbl.data = net->sctp.sctp_hmac_alg ? : none;
322 tbl.maxlen = strlen(tbl.data);
323 }
324 ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
325
326 if (write) {
327#ifdef CONFIG_CRYPTO_MD5
328 if (!strncmp(tmp, "md5", 3)) {
329 net->sctp.sctp_hmac_alg = "md5";
330 changed = 1;
331 }
332#endif
333#ifdef CONFIG_CRYPTO_SHA1
334 if (!strncmp(tmp, "sha1", 4)) {
335 net->sctp.sctp_hmac_alg = "sha1";
336 changed = 1;
337 }
338#endif
339 if (!strncmp(tmp, "none", 4)) {
340 net->sctp.sctp_hmac_alg = NULL;
341 changed = 1;
342 }
343
344 if (!changed)
345 ret = -EINVAL;
346 }
347
348 return ret;
349}
350
292int sctp_sysctl_net_register(struct net *net) 351int sctp_sysctl_net_register(struct net *net)
293{ 352{
294 struct ctl_table *table; 353 struct ctl_table *table;