wok diff linux/stuff/linux-tcp_stealth.u @ rev 23254
updated nzbget (13.0 -> 21.0)
author | Hans-G?nter Theisgen |
---|---|
date | Wed Mar 25 16:49:46 2020 +0100 (2020-03-25) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linux/stuff/linux-tcp_stealth.u Wed Mar 25 16:49:46 2020 +0100 1.3 @@ -0,0 +1,630 @@ 1.4 +From https://gnunet.org/knock : 1.5 +https://gnunet.org/sites/default/files/tcp_stealth_3.16_1.diff 1.6 +Signed-off-by: Julian Kirsch <kirschju@sec.in.tum.de> 1.7 +--- 1.8 +diff -Nurp linux-3.16/include/linux/tcp.h linux-3.16-knock/include/linux/tcp.h 1.9 +--- linux-3.16/include/linux/tcp.h 2014-08-03 18:25:02.000000000 -0400 1.10 ++++ linux-3.16-knock/include/linux/tcp.h 2014-08-19 06:15:42.329509665 -0400 1.11 +@@ -20,6 +20,7 @@ 1.12 + 1.13 + #include <linux/skbuff.h> 1.14 + #include <linux/dmaengine.h> 1.15 ++#include <linux/cryptohash.h> 1.16 + #include <net/sock.h> 1.17 + #include <net/inet_connection_sock.h> 1.18 + #include <net/inet_timewait_sock.h> 1.19 +@@ -325,6 +326,21 @@ struct tcp_sock { 1.20 + struct tcp_md5sig_info __rcu *md5sig_info; 1.21 + #endif 1.22 + 1.23 ++#ifdef CONFIG_TCP_STEALTH 1.24 ++/* Stealth TCP socket configuration */ 1.25 ++ struct { 1.26 ++ #define TCP_STEALTH_MODE_AUTH BIT(0) 1.27 ++ #define TCP_STEALTH_MODE_INTEGRITY BIT(1) 1.28 ++ #define TCP_STEALTH_MODE_INTEGRITY_LEN BIT(2) 1.29 ++ int mode; 1.30 ++ u8 secret[MD5_MESSAGE_BYTES]; 1.31 ++ int integrity_len; 1.32 ++ u16 integrity_hash; 1.33 ++ u32 tsval; 1.34 ++ bool saw_tsval; 1.35 ++ } stealth; 1.36 ++#endif 1.37 ++ 1.38 + /* TCP fastopen related information */ 1.39 + struct tcp_fastopen_request *fastopen_req; 1.40 + /* fastopen_rsk points to request_sock that resulted in this big 1.41 +diff -Nurp linux-3.16/include/net/secure_seq.h linux-3.16-knock/include/net/secure_seq.h 1.42 +--- linux-3.16/include/net/secure_seq.h 2014-08-03 18:25:02.000000000 -0400 1.43 ++++ linux-3.16-knock/include/net/secure_seq.h 2014-08-19 05:52:22.389447048 -0400 1.44 +@@ -14,5 +14,10 @@ u64 secure_dccp_sequence_number(__be32 s 1.45 + __be16 sport, __be16 dport); 1.46 + u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, 1.47 + __be16 sport, __be16 dport); 1.48 ++#ifdef CONFIG_TCP_STEALTH 1.49 ++u32 tcp_stealth_do_auth(struct sock *sk, struct sk_buff *skb); 1.50 ++u32 tcp_stealth_sequence_number(struct sock *sk, __be32 *daddr, 1.51 ++ u32 daddr_size, __be16 dport); 1.52 ++#endif 1.53 + 1.54 + #endif /* _NET_SECURE_SEQ */ 1.55 +diff -Nurp linux-3.16/include/net/tcp.h linux-3.16-knock/include/net/tcp.h 1.56 +--- linux-3.16/include/net/tcp.h 2014-08-03 18:25:02.000000000 -0400 1.57 ++++ linux-3.16-knock/include/net/tcp.h 2014-08-11 07:16:15.968418122 -0400 1.58 +@@ -442,6 +442,12 @@ void tcp_parse_options(const struct sk_b 1.59 + struct tcp_options_received *opt_rx, 1.60 + int estab, struct tcp_fastopen_cookie *foc); 1.61 + const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); 1.62 ++#ifdef CONFIG_TCP_STEALTH 1.63 ++const bool tcp_parse_tsval_option(u32 *tsval, const struct tcphdr *th); 1.64 ++int tcp_stealth_integrity(u16 *hash, u8 *secret, u8 *payload, int len); 1.65 ++#define be32_isn_to_be16_av(x) (((__be16 *)&x)[0]) 1.66 ++#define be32_isn_to_be16_ih(x) (((__be16 *)&x)[1]) 1.67 ++#endif 1.68 + 1.69 + /* 1.70 + * TCP v4 functions exported for the inet6 API 1.71 +diff -Nurp linux-3.16/include/uapi/linux/tcp.h linux-3.16-knock/include/uapi/linux/tcp.h 1.72 +--- linux-3.16/include/uapi/linux/tcp.h 2014-08-03 18:25:02.000000000 -0400 1.73 ++++ linux-3.16-knock/include/uapi/linux/tcp.h 2014-08-11 07:16:15.968418122 -0400 1.74 +@@ -112,6 +112,9 @@ enum { 1.75 + #define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ 1.76 + #define TCP_TIMESTAMP 24 1.77 + #define TCP_NOTSENT_LOWAT 25 /* limit number of unsent bytes in write queue */ 1.78 ++#define TCP_STEALTH 26 1.79 ++#define TCP_STEALTH_INTEGRITY 27 1.80 ++#define TCP_STEALTH_INTEGRITY_LEN 28 1.81 + 1.82 + struct tcp_repair_opt { 1.83 + __u32 opt_code; 1.84 +diff -Nurp linux-3.16/net/core/secure_seq.c linux-3.16-knock/net/core/secure_seq.c 1.85 +--- linux-3.16/net/core/secure_seq.c 2014-08-03 18:25:02.000000000 -0400 1.86 ++++ linux-3.16-knock/net/core/secure_seq.c 2014-08-19 06:19:31.241519904 -0400 1.87 +@@ -8,7 +8,11 @@ 1.88 + #include <linux/ktime.h> 1.89 + #include <linux/string.h> 1.90 + #include <linux/net.h> 1.91 ++#include <linux/socket.h> 1.92 ++#include <linux/ip.h> 1.93 ++#include <linux/ipv6.h> 1.94 + 1.95 ++#include <net/tcp.h> 1.96 + #include <net/secure_seq.h> 1.97 + 1.98 + #if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_INET) 1.99 +@@ -39,6 +43,102 @@ static u32 seq_scale(u32 seq) 1.100 + } 1.101 + #endif 1.102 + 1.103 ++#ifdef CONFIG_TCP_STEALTH 1.104 ++u32 tcp_stealth_sequence_number(struct sock *sk, __be32 *daddr, 1.105 ++ u32 daddr_size, __be16 dport) 1.106 ++{ 1.107 ++ struct tcp_sock *tp = tcp_sk(sk); 1.108 ++ struct tcp_md5sig_key *md5; 1.109 ++ 1.110 ++ __u32 sec[MD5_MESSAGE_BYTES / sizeof(__u32)]; 1.111 ++ __u32 i; 1.112 ++ __u32 tsval = 0; 1.113 ++ 1.114 ++ __be32 iv[MD5_DIGEST_WORDS] = { 0 }; 1.115 ++ __be32 isn; 1.116 ++ 1.117 ++ memcpy(iv, (const __u8 *)daddr, 1.118 ++ (daddr_size > sizeof(iv)) ? sizeof(iv) : daddr_size); 1.119 ++ 1.120 ++#ifdef CONFIG_TCP_MD5SIG 1.121 ++ md5 = tp->af_specific->md5_lookup(sk, sk); 1.122 ++#else 1.123 ++ md5 = NULL; 1.124 ++#endif 1.125 ++ if (likely(sysctl_tcp_timestamps && !md5) || tp->stealth.saw_tsval) 1.126 ++ tsval = tp->stealth.tsval; 1.127 ++ 1.128 ++ ((__be16 *)iv)[2] ^= cpu_to_be16(tp->stealth.integrity_hash); 1.129 ++ iv[2] ^= cpu_to_be32(tsval); 1.130 ++ ((__be16 *)iv)[6] ^= dport; 1.131 ++ 1.132 ++ for (i = 0; i < MD5_DIGEST_WORDS; i++) 1.133 ++ iv[i] = le32_to_cpu(iv[i]); 1.134 ++ for (i = 0; i < MD5_MESSAGE_BYTES / sizeof(__le32); i++) 1.135 ++ sec[i] = le32_to_cpu(((__le32 *)tp->stealth.secret)[i]); 1.136 ++ 1.137 ++ md5_transform(iv, sec); 1.138 ++ 1.139 ++ isn = cpu_to_be32(iv[0]) ^ cpu_to_be32(iv[1]) ^ 1.140 ++ cpu_to_be32(iv[2]) ^ cpu_to_be32(iv[3]); 1.141 ++ 1.142 ++ if (tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY) 1.143 ++ be32_isn_to_be16_ih(isn) = 1.144 ++ cpu_to_be16(tp->stealth.integrity_hash); 1.145 ++ 1.146 ++ return be32_to_cpu(isn); 1.147 ++} 1.148 ++EXPORT_SYMBOL(tcp_stealth_sequence_number); 1.149 ++ 1.150 ++u32 tcp_stealth_do_auth(struct sock *sk, struct sk_buff *skb) 1.151 ++{ 1.152 ++ struct tcp_sock *tp = tcp_sk(sk); 1.153 ++ struct tcphdr *th = tcp_hdr(skb); 1.154 ++ __be32 isn = th->seq; 1.155 ++ __be32 hash; 1.156 ++ __be32 *daddr; 1.157 ++ u32 daddr_size; 1.158 ++ 1.159 ++ tp->stealth.saw_tsval = tcp_parse_tsval_option(&tp->stealth.tsval, th); 1.160 ++ 1.161 ++ if (tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN) 1.162 ++ tp->stealth.integrity_hash = 1.163 ++ be16_to_cpu(be32_isn_to_be16_ih(isn)); 1.164 ++ 1.165 ++ switch (tp->inet_conn.icsk_inet.sk.sk_family) { 1.166 ++#if IS_ENABLED(CONFIG_IPV6) 1.167 ++ case PF_INET6: 1.168 ++ daddr_size = sizeof(ipv6_hdr(skb)->daddr.s6_addr32); 1.169 ++ daddr = ipv6_hdr(skb)->daddr.s6_addr32; 1.170 ++ break; 1.171 ++#endif 1.172 ++ case PF_INET: 1.173 ++ daddr_size = sizeof(ip_hdr(skb)->daddr); 1.174 ++ daddr = &ip_hdr(skb)->daddr; 1.175 ++ break; 1.176 ++ default: 1.177 ++ pr_err("TCP Stealth: Unknown network layer protocol, stop!\n"); 1.178 ++ return 1; 1.179 ++ } 1.180 ++ 1.181 ++ hash = tcp_stealth_sequence_number(sk, daddr, daddr_size, th->dest); 1.182 ++ cpu_to_be32s(&hash); 1.183 ++ 1.184 ++ if (tp->stealth.mode & TCP_STEALTH_MODE_AUTH && 1.185 ++ tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN && 1.186 ++ be32_isn_to_be16_av(isn) == be32_isn_to_be16_av(hash)) 1.187 ++ return 0; 1.188 ++ 1.189 ++ if (tp->stealth.mode & TCP_STEALTH_MODE_AUTH && 1.190 ++ !(tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN) && 1.191 ++ isn == hash) 1.192 ++ return 0; 1.193 ++ 1.194 ++ return 1; 1.195 ++} 1.196 ++EXPORT_SYMBOL(tcp_stealth_do_auth); 1.197 ++#endif 1.198 ++ 1.199 + #if IS_ENABLED(CONFIG_IPV6) 1.200 + __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, 1.201 + __be16 sport, __be16 dport) 1.202 +diff -Nurp linux-3.16/net/ipv4/Kconfig linux-3.16-knock/net/ipv4/Kconfig 1.203 +--- linux-3.16/net/ipv4/Kconfig 2014-08-03 18:25:02.000000000 -0400 1.204 ++++ linux-3.16-knock/net/ipv4/Kconfig 2014-08-11 07:16:15.968418122 -0400 1.205 +@@ -618,3 +618,13 @@ config TCP_MD5SIG 1.206 + on the Internet. 1.207 + 1.208 + If unsure, say N. 1.209 ++ 1.210 ++config TCP_STEALTH 1.211 ++ bool "TCP: Stealth TCP socket support" 1.212 ++ default n 1.213 ++ ---help--- 1.214 ++ This option enables support for stealth TCP sockets. If you do not 1.215 ++ know what this means, you do not need it. 1.216 ++ 1.217 ++ If unsure, say N. 1.218 ++ 1.219 +diff -Nurp linux-3.16/net/ipv4/tcp.c linux-3.16-knock/net/ipv4/tcp.c 1.220 +--- linux-3.16/net/ipv4/tcp.c 2014-08-03 18:25:02.000000000 -0400 1.221 ++++ linux-3.16-knock/net/ipv4/tcp.c 2014-08-19 06:17:19.497514011 -0400 1.222 +@@ -2443,6 +2443,43 @@ static int tcp_repair_options_est(struct 1.223 + return 0; 1.224 + } 1.225 + 1.226 ++#ifdef CONFIG_TCP_STEALTH 1.227 ++int tcp_stealth_integrity(__be16 *hash, u8 *secret, u8 *payload, int len) 1.228 ++{ 1.229 ++ struct scatterlist sg[2]; 1.230 ++ struct crypto_hash *tfm; 1.231 ++ struct hash_desc desc; 1.232 ++ __be16 h[MD5_DIGEST_WORDS * 2]; 1.233 ++ int i; 1.234 ++ int err = 0; 1.235 ++ 1.236 ++ tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC); 1.237 ++ if (IS_ERR(tfm)) { 1.238 ++ err = -PTR_ERR(tfm); 1.239 ++ goto out; 1.240 ++ } 1.241 ++ desc.tfm = tfm; 1.242 ++ desc.flags = 0; 1.243 ++ 1.244 ++ sg_init_table(sg, 2); 1.245 ++ sg_set_buf(&sg[0], secret, MD5_MESSAGE_BYTES); 1.246 ++ sg_set_buf(&sg[1], payload, len); 1.247 ++ 1.248 ++ if (crypto_hash_digest(&desc, sg, MD5_MESSAGE_BYTES + len, (u8 *)h)) { 1.249 ++ err = -EFAULT; 1.250 ++ goto out; 1.251 ++ } 1.252 ++ 1.253 ++ *hash = be16_to_cpu(h[0]); 1.254 ++ for (i = 1; i < MD5_DIGEST_WORDS * 2; i++) 1.255 ++ *hash ^= be16_to_cpu(h[i]); 1.256 ++ 1.257 ++out: 1.258 ++ crypto_free_hash(tfm); 1.259 ++ return err; 1.260 ++} 1.261 ++#endif 1.262 ++ 1.263 + /* 1.264 + * Socket option code for TCP. 1.265 + */ 1.266 +@@ -2473,6 +2510,67 @@ static int do_tcp_setsockopt(struct sock 1.267 + release_sock(sk); 1.268 + return err; 1.269 + } 1.270 ++#ifdef CONFIG_TCP_STEALTH 1.271 ++ case TCP_STEALTH: { 1.272 ++ u8 secret[MD5_MESSAGE_BYTES]; 1.273 ++ 1.274 ++ if (optlen < MD5_MESSAGE_BYTES) 1.275 ++ return -EINVAL; 1.276 ++ 1.277 ++ val = copy_from_user(secret, optval, MD5_MESSAGE_BYTES); 1.278 ++ if (val != 0) 1.279 ++ return -EFAULT; 1.280 ++ 1.281 ++ lock_sock(sk); 1.282 ++ memcpy(tp->stealth.secret, secret, MD5_MESSAGE_BYTES); 1.283 ++ tp->stealth.mode = TCP_STEALTH_MODE_AUTH; 1.284 ++ tp->stealth.tsval = 0; 1.285 ++ tp->stealth.saw_tsval = false; 1.286 ++ release_sock(sk); 1.287 ++ return err; 1.288 ++ } 1.289 ++ case TCP_STEALTH_INTEGRITY: { 1.290 ++ u8 *payload; 1.291 ++ 1.292 ++ lock_sock(sk); 1.293 ++ 1.294 ++ if (!(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) { 1.295 ++ err = -EOPNOTSUPP; 1.296 ++ goto stealth_integrity_out_1; 1.297 ++ } 1.298 ++ 1.299 ++ if (optlen < 1 || optlen > USHRT_MAX) { 1.300 ++ err = -EINVAL; 1.301 ++ goto stealth_integrity_out_1; 1.302 ++ } 1.303 ++ 1.304 ++ payload = vmalloc(optlen); 1.305 ++ if (!payload) { 1.306 ++ err = -ENOMEM; 1.307 ++ goto stealth_integrity_out_1; 1.308 ++ } 1.309 ++ 1.310 ++ val = copy_from_user(payload, optval, optlen); 1.311 ++ if (val != 0) { 1.312 ++ err = -EFAULT; 1.313 ++ goto stealth_integrity_out_2; 1.314 ++ } 1.315 ++ 1.316 ++ err = tcp_stealth_integrity(&tp->stealth.integrity_hash, 1.317 ++ tp->stealth.secret, payload, 1.318 ++ optlen); 1.319 ++ if (err) 1.320 ++ goto stealth_integrity_out_2; 1.321 ++ 1.322 ++ tp->stealth.mode |= TCP_STEALTH_MODE_INTEGRITY; 1.323 ++ 1.324 ++stealth_integrity_out_2: 1.325 ++ vfree(payload); 1.326 ++stealth_integrity_out_1: 1.327 ++ release_sock(sk); 1.328 ++ return err; 1.329 ++ } 1.330 ++#endif 1.331 + default: 1.332 + /* fallthru */ 1.333 + break; 1.334 +@@ -2717,6 +2815,18 @@ static int do_tcp_setsockopt(struct sock 1.335 + tp->notsent_lowat = val; 1.336 + sk->sk_write_space(sk); 1.337 + break; 1.338 ++#ifdef CONFIG_TCP_STEALTH 1.339 ++ case TCP_STEALTH_INTEGRITY_LEN: 1.340 ++ if (!(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) { 1.341 ++ err = -EOPNOTSUPP; 1.342 ++ } else if (val < 1 || val > USHRT_MAX) { 1.343 ++ err = -EINVAL; 1.344 ++ } else { 1.345 ++ tp->stealth.integrity_len = val; 1.346 ++ tp->stealth.mode |= TCP_STEALTH_MODE_INTEGRITY_LEN; 1.347 ++ } 1.348 ++ break; 1.349 ++#endif 1.350 + default: 1.351 + err = -ENOPROTOOPT; 1.352 + break; 1.353 +diff -Nurp linux-3.16/net/ipv4/tcp_input.c linux-3.16-knock/net/ipv4/tcp_input.c 1.354 +--- linux-3.16/net/ipv4/tcp_input.c 2014-08-03 18:25:02.000000000 -0400 1.355 ++++ linux-3.16-knock/net/ipv4/tcp_input.c 2014-08-18 13:08:23.956054243 -0400 1.356 +@@ -76,6 +76,9 @@ 1.357 + #include <net/netdma.h> 1.358 + 1.359 + int sysctl_tcp_timestamps __read_mostly = 1; 1.360 ++#ifdef CONFIG_TCP_STEALTH 1.361 ++EXPORT_SYMBOL(sysctl_tcp_timestamps); 1.362 ++#endif 1.363 + int sysctl_tcp_window_scaling __read_mostly = 1; 1.364 + int sysctl_tcp_sack __read_mostly = 1; 1.365 + int sysctl_tcp_fack __read_mostly = 1; 1.366 +@@ -3666,6 +3669,47 @@ static bool tcp_fast_parse_options(const 1.367 + return true; 1.368 + } 1.369 + 1.370 ++#ifdef CONFIG_TCP_STEALTH 1.371 ++/* Parse only the TSVal field of the TCP Timestamp option header. 1.372 ++ */ 1.373 ++const bool tcp_parse_tsval_option(u32 *tsval, const struct tcphdr *th) 1.374 ++{ 1.375 ++ int length = (th->doff << 2) - sizeof(*th); 1.376 ++ const u8 *ptr = (const u8 *)(th + 1); 1.377 ++ 1.378 ++ /* If the TCP option is too short, we can short cut */ 1.379 ++ if (length < TCPOLEN_TIMESTAMP) 1.380 ++ return false; 1.381 ++ 1.382 ++ while (length > 0) { 1.383 ++ int opcode = *ptr++; 1.384 ++ int opsize; 1.385 ++ 1.386 ++ switch (opcode) { 1.387 ++ case TCPOPT_EOL: 1.388 ++ return false; 1.389 ++ case TCPOPT_NOP: 1.390 ++ length--; 1.391 ++ continue; 1.392 ++ case TCPOPT_TIMESTAMP: 1.393 ++ opsize = *ptr++; 1.394 ++ if (opsize != TCPOLEN_TIMESTAMP || opsize > length) 1.395 ++ return false; 1.396 ++ *tsval = get_unaligned_be32(ptr); 1.397 ++ return true; 1.398 ++ default: 1.399 ++ opsize = *ptr++; 1.400 ++ if (opsize < 2 || opsize > length) 1.401 ++ return false; 1.402 ++ } 1.403 ++ ptr += opsize - 2; 1.404 ++ length -= opsize; 1.405 ++ } 1.406 ++ return false; 1.407 ++} 1.408 ++EXPORT_SYMBOL(tcp_parse_tsval_option); 1.409 ++#endif 1.410 ++ 1.411 + #ifdef CONFIG_TCP_MD5SIG 1.412 + /* 1.413 + * Parse MD5 Signature option 1.414 +@@ -4337,6 +4381,31 @@ err: 1.415 + return -ENOMEM; 1.416 + } 1.417 + 1.418 ++#ifdef CONFIG_TCP_STEALTH 1.419 ++static int __tcp_stealth_integrity_check(struct sock *sk, struct sk_buff *skb) 1.420 ++{ 1.421 ++ struct tcphdr *th = tcp_hdr(skb); 1.422 ++ struct tcp_sock *tp = tcp_sk(sk); 1.423 ++ u16 hash; 1.424 ++ __be32 seq = cpu_to_be32(TCP_SKB_CB(skb)->seq - 1); 1.425 ++ char *data = skb->data + th->doff * 4; 1.426 ++ int len = skb->len - th->doff * 4; 1.427 ++ 1.428 ++ if (len < tp->stealth.integrity_len) 1.429 ++ return 1; 1.430 ++ 1.431 ++ if (tcp_stealth_integrity(&hash, tp->stealth.secret, data, 1.432 ++ tp->stealth.integrity_len)) 1.433 ++ return 1; 1.434 ++ 1.435 ++ if (be32_isn_to_be16_ih(seq) != cpu_to_be16(hash)) 1.436 ++ return 1; 1.437 ++ 1.438 ++ tp->stealth.mode &= ~TCP_STEALTH_MODE_INTEGRITY_LEN; 1.439 ++ return 0; 1.440 ++} 1.441 ++#endif 1.442 ++ 1.443 + static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) 1.444 + { 1.445 + const struct tcphdr *th = tcp_hdr(skb); 1.446 +@@ -4347,6 +4416,14 @@ static void tcp_data_queue(struct sock * 1.447 + if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) 1.448 + goto drop; 1.449 + 1.450 ++#ifdef CONFIG_TCP_STEALTH 1.451 ++ if (unlikely(tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN) && 1.452 ++ __tcp_stealth_integrity_check(sk, skb)) { 1.453 ++ tcp_reset(sk); 1.454 ++ goto drop; 1.455 ++ } 1.456 ++#endif 1.457 ++ 1.458 + skb_dst_drop(skb); 1.459 + __skb_pull(skb, th->doff * 4); 1.460 + 1.461 +@@ -5171,6 +5248,15 @@ void tcp_rcv_established(struct sock *sk 1.462 + int copied_early = 0; 1.463 + bool fragstolen = false; 1.464 + 1.465 ++#ifdef CONFIG_TCP_STEALTH 1.466 ++ if (unlikely(tp->stealth.mode & 1.467 ++ TCP_STEALTH_MODE_INTEGRITY_LEN) && 1.468 ++ __tcp_stealth_integrity_check(sk, skb)) { 1.469 ++ tcp_reset(sk); 1.470 ++ goto discard; 1.471 ++ } 1.472 ++#endif 1.473 ++ 1.474 + if (tp->copied_seq == tp->rcv_nxt && 1.475 + len - tcp_header_len <= tp->ucopy.len) { 1.476 + #ifdef CONFIG_NET_DMA 1.477 +diff -Nurp linux-3.16/net/ipv4/tcp_ipv4.c linux-3.16-knock/net/ipv4/tcp_ipv4.c 1.478 +--- linux-3.16/net/ipv4/tcp_ipv4.c 2014-08-03 18:25:02.000000000 -0400 1.479 ++++ linux-3.16-knock/net/ipv4/tcp_ipv4.c 2014-08-19 05:50:27.217441897 -0400 1.480 +@@ -76,6 +76,7 @@ 1.481 + #include <net/secure_seq.h> 1.482 + #include <net/tcp_memcontrol.h> 1.483 + #include <net/busy_poll.h> 1.484 ++#include <net/secure_seq.h> 1.485 + 1.486 + #include <linux/inet.h> 1.487 + #include <linux/ipv6.h> 1.488 +@@ -235,6 +236,21 @@ int tcp_v4_connect(struct sock *sk, stru 1.489 + sk->sk_gso_type = SKB_GSO_TCPV4; 1.490 + sk_setup_caps(sk, &rt->dst); 1.491 + 1.492 ++#ifdef CONFIG_TCP_STEALTH 1.493 ++ /* If CONFIG_TCP_STEALTH is defined, we need to know the timestamp as 1.494 ++ * early as possible and thus move taking the snapshot of tcp_time_stamp 1.495 ++ * here. 1.496 ++ */ 1.497 ++ tp->stealth.tsval = tcp_time_stamp; 1.498 ++ 1.499 ++ if (!tp->write_seq && likely(!tp->repair) && 1.500 ++ unlikely(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) 1.501 ++ tp->write_seq = tcp_stealth_sequence_number(sk, 1.502 ++ &inet->inet_daddr, 1.503 ++ sizeof(inet->inet_daddr), 1.504 ++ usin->sin_port); 1.505 ++#endif 1.506 ++ 1.507 + if (!tp->write_seq && likely(!tp->repair)) 1.508 + tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr, 1.509 + inet->inet_daddr, 1.510 +@@ -1546,6 +1562,8 @@ static struct sock *tcp_v4_hnd_req(struc 1.511 + */ 1.512 + int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) 1.513 + { 1.514 ++ struct tcp_sock *tp = tcp_sk(sk); 1.515 ++ struct tcphdr *th = tcp_hdr(skb); 1.516 + struct sock *rsk; 1.517 + #ifdef CONFIG_TCP_MD5SIG 1.518 + /* 1.519 +@@ -1576,6 +1594,15 @@ int tcp_v4_do_rcv(struct sock *sk, struc 1.520 + if (skb->len < tcp_hdrlen(skb) || tcp_checksum_complete(skb)) 1.521 + goto csum_err; 1.522 + 1.523 ++#ifdef CONFIG_TCP_STEALTH 1.524 ++ if (sk->sk_state == TCP_LISTEN && th->syn && !th->fin && 1.525 ++ unlikely(tp->stealth.mode & TCP_STEALTH_MODE_AUTH) && 1.526 ++ tcp_stealth_do_auth(sk, skb)) { 1.527 ++ rsk = sk; 1.528 ++ goto reset; 1.529 ++ } 1.530 ++#endif 1.531 ++ 1.532 + if (sk->sk_state == TCP_LISTEN) { 1.533 + struct sock *nsk = tcp_v4_hnd_req(sk, skb); 1.534 + if (!nsk) 1.535 +diff -Nurp linux-3.16/net/ipv4/tcp_output.c linux-3.16-knock/net/ipv4/tcp_output.c 1.536 +--- linux-3.16/net/ipv4/tcp_output.c 2014-08-03 18:25:02.000000000 -0400 1.537 ++++ linux-3.16-knock/net/ipv4/tcp_output.c 2014-08-11 07:29:32.776405670 -0400 1.538 +@@ -2486,10 +2486,22 @@ int __tcp_retransmit_skb(struct sock *sk 1.539 + 1.540 + tcp_retrans_try_collapse(sk, skb, cur_mss); 1.541 + 1.542 ++#ifdef CONFIG_TCP_STEALTH 1.543 ++ if (unlikely(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN && 1.544 ++ tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) { 1.545 ++ /* If TCP stealth is active, reuse the timestamp from the first 1.546 ++ * SYN. 1.547 ++ */ 1.548 ++ TCP_SKB_CB(skb)->when = tp->stealth.tsval; 1.549 ++ } else { 1.550 ++ TCP_SKB_CB(skb)->when = tcp_time_stamp; 1.551 ++ } 1.552 ++#else 1.553 + /* Make a copy, if the first transmission SKB clone we made 1.554 + * is still in somebody's hands, else make a clone. 1.555 + */ 1.556 + TCP_SKB_CB(skb)->when = tcp_time_stamp; 1.557 ++#endif 1.558 + 1.559 + /* make sure skb->data is aligned on arches that require it 1.560 + * and check if ack-trimming & collapsing extended the headroom 1.561 +@@ -3094,7 +3106,15 @@ int tcp_connect(struct sock *sk) 1.562 + return -ENOBUFS; 1.563 + 1.564 + tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN); 1.565 ++#ifdef CONFIG_TCP_STEALTH 1.566 ++ /* The timetamp was already set at the time the ISN was generated 1.567 ++ * as we need to know its value in the stealth_tcp_sequence_number() 1.568 ++ * function. 1.569 ++ */ 1.570 ++ tp->retrans_stamp = TCP_SKB_CB(buff)->when = tp->stealth.tsval; 1.571 ++#else 1.572 + tp->retrans_stamp = TCP_SKB_CB(buff)->when = tcp_time_stamp; 1.573 ++#endif 1.574 + tcp_connect_queue_skb(sk, buff); 1.575 + TCP_ECN_send_syn(sk, buff); 1.576 + 1.577 +diff -Nurp linux-3.16/net/ipv6/tcp_ipv6.c linux-3.16-knock/net/ipv6/tcp_ipv6.c 1.578 +--- linux-3.16/net/ipv6/tcp_ipv6.c 2014-08-03 18:25:02.000000000 -0400 1.579 ++++ linux-3.16-knock/net/ipv6/tcp_ipv6.c 2014-08-19 06:24:12.497532484 -0400 1.580 +@@ -64,6 +64,7 @@ 1.581 + #include <net/secure_seq.h> 1.582 + #include <net/tcp_memcontrol.h> 1.583 + #include <net/busy_poll.h> 1.584 ++#include <net/secure_seq.h> 1.585 + 1.586 + #include <linux/proc_fs.h> 1.587 + #include <linux/seq_file.h> 1.588 +@@ -294,6 +295,21 @@ static int tcp_v6_connect(struct sock *s 1.589 + if (err) 1.590 + goto late_failure; 1.591 + 1.592 ++#ifdef CONFIG_TCP_STEALTH 1.593 ++ /* If CONFIG_TCP_STEALTH is defined, we need to know the timestamp as 1.594 ++ * early as possible and thus move taking the snapshot of tcp_time_stamp 1.595 ++ * here. 1.596 ++ */ 1.597 ++ tp->stealth.tsval = tcp_time_stamp; 1.598 ++ 1.599 ++ if (!tp->write_seq && likely(!tp->repair) && 1.600 ++ unlikely(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) 1.601 ++ tp->write_seq = tcp_stealth_sequence_number(sk, 1.602 ++ sk->sk_v6_daddr.s6_addr32, 1.603 ++ sizeof(sk->sk_v6_daddr), 1.604 ++ inet->inet_dport); 1.605 ++#endif 1.606 ++ 1.607 + if (!tp->write_seq && likely(!tp->repair)) 1.608 + tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, 1.609 + sk->sk_v6_daddr.s6_addr32, 1.610 +@@ -1343,7 +1359,8 @@ out: 1.611 + static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) 1.612 + { 1.613 + struct ipv6_pinfo *np = inet6_sk(sk); 1.614 +- struct tcp_sock *tp; 1.615 ++ struct tcp_sock *tp = tcp_sk(sk); 1.616 ++ struct tcphdr *th = tcp_hdr(skb); 1.617 + struct sk_buff *opt_skb = NULL; 1.618 + 1.619 + /* Imagine: socket is IPv6. IPv4 packet arrives, 1.620 +@@ -1407,6 +1424,13 @@ static int tcp_v6_do_rcv(struct sock *sk 1.621 + if (skb->len < tcp_hdrlen(skb) || tcp_checksum_complete(skb)) 1.622 + goto csum_err; 1.623 + 1.624 ++#ifdef CONFIG_TCP_STEALTH 1.625 ++ if (sk->sk_state == TCP_LISTEN && th->syn && !th->fin && 1.626 ++ tp->stealth.mode & TCP_STEALTH_MODE_AUTH && 1.627 ++ tcp_stealth_do_auth(sk, skb)) 1.628 ++ goto reset; 1.629 ++#endif 1.630 ++ 1.631 + if (sk->sk_state == TCP_LISTEN) { 1.632 + struct sock *nsk = tcp_v6_hnd_req(sk, skb); 1.633 + if (!nsk)