Commit 3cd1c67c authored by Matt Mackall's avatar Matt Mackall Committed by Linus Torvalds

[PATCH] random: Simplify and shrink syncookie code

Simplify syncookie initialization
Refactor syncookie code with separate hash function
Signed-off-by: default avatarMatt Mackall <mpm@selenic.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 567200b8
...@@ -366,6 +366,10 @@ static struct poolinfo { ...@@ -366,6 +366,10 @@ static struct poolinfo {
* hash; hash collisions will occur no more often than chance. * hash; hash collisions will occur no more often than chance.
*/ */
#ifdef CONFIG_SYN_COOKIES
static __u32 syncookie_secret[2][16-3+SHA_WORKSPACE_WORDS];
#endif
/* /*
* Static global variables * Static global variables
*/ */
...@@ -897,6 +901,9 @@ static int __init rand_initialize(void) ...@@ -897,6 +901,9 @@ static int __init rand_initialize(void)
init_std_data(&input_pool); init_std_data(&input_pool);
init_std_data(&blocking_pool); init_std_data(&blocking_pool);
init_std_data(&nonblocking_pool); init_std_data(&nonblocking_pool);
#ifdef CONFIG_SYN_COOKIES
get_random_bytes(syncookie_secret, sizeof(syncookie_secret));
#endif
return 0; return 0;
} }
module_init(rand_initialize); module_init(rand_initialize);
...@@ -1601,23 +1608,24 @@ EXPORT_SYMBOL(secure_tcpv6_port_ephemeral); ...@@ -1601,23 +1608,24 @@ EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
#define COOKIEBITS 24 /* Upper bits store count */ #define COOKIEBITS 24 /* Upper bits store count */
#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
static int syncookie_init; static u32 cookie_hash(u32 saddr, u32 daddr, u32 sport, u32 dport,
static __u32 syncookie_secret[2][16-3+SHA_DIGEST_WORDS]; u32 count, int c)
__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
__u16 dport, __u32 sseq, __u32 count, __u32 data)
{ {
__u32 tmp[16 + 5 + SHA_WORKSPACE_WORDS]; __u32 tmp[16 + 5 + SHA_WORKSPACE_WORDS];
__u32 seq;
/* memcpy(tmp + 3, syncookie_secret[c], sizeof(syncookie_secret[c]));
* Pick two random secrets the first time we need a cookie. tmp[0] = saddr;
*/ tmp[1] = daddr;
if (syncookie_init == 0) { tmp[2] = (sport << 16) + dport;
get_random_bytes(syncookie_secret, sizeof(syncookie_secret)); tmp[3] = count;
syncookie_init = 1; sha_transform(tmp + 16, tmp);
}
return tmp[17];
}
__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
__u16 dport, __u32 sseq, __u32 count, __u32 data)
{
/* /*
* Compute the secure sequence number. * Compute the secure sequence number.
* The output should be: * The output should be:
...@@ -1629,22 +1637,10 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport, ...@@ -1629,22 +1637,10 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
* MSS into the second hash value. * MSS into the second hash value.
*/ */
memcpy(tmp + 3, syncookie_secret[0], sizeof(syncookie_secret[0])); return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
tmp[0]=saddr; sseq + (count << COOKIEBITS) +
tmp[1]=daddr; ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
tmp[2]=(sport << 16) + dport; & COOKIEMASK));
sha_transform(tmp+16, (__u8 *)tmp, tmp + 16 + 5);
seq = tmp[17] + sseq + (count << COOKIEBITS);
memcpy(tmp + 3, syncookie_secret[1], sizeof(syncookie_secret[1]));
tmp[0]=saddr;
tmp[1]=daddr;
tmp[2]=(sport << 16) + dport;
tmp[3] = count; /* minute counter */
sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5);
/* Add in the second hash and the data */
return seq + ((tmp[17] + data) & COOKIEMASK);
} }
/* /*
...@@ -1659,33 +1655,19 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport, ...@@ -1659,33 +1655,19 @@ __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
__u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport, __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
__u16 dport, __u32 sseq, __u32 count, __u32 maxdiff) __u16 dport, __u32 sseq, __u32 count, __u32 maxdiff)
{ {
__u32 tmp[16 + 5 + SHA_WORKSPACE_WORDS];
__u32 diff; __u32 diff;
if (syncookie_init == 0)
return (__u32)-1; /* Well, duh! */
/* Strip away the layers from the cookie */ /* Strip away the layers from the cookie */
memcpy(tmp + 3, syncookie_secret[0], sizeof(syncookie_secret[0])); cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;
tmp[0]=saddr;
tmp[1]=daddr;
tmp[2]=(sport << 16) + dport;
sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5);
cookie -= tmp[17] + sseq;
/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS); diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS);
if (diff >= maxdiff) if (diff >= maxdiff)
return (__u32)-1; return (__u32)-1;
memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1])); return (cookie -
tmp[0] = saddr; cookie_hash(saddr, daddr, sport, dport, count - diff, 1))
tmp[1] = daddr; & COOKIEMASK; /* Leaving the data behind */
tmp[2] = (sport << 16) + dport;
tmp[3] = count - diff; /* minute counter */
sha_transform(tmp + 16, tmp);
return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
} }
#endif #endif
#endif /* CONFIG_INET */ #endif /* CONFIG_INET */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment