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)