diff options
-rw-r--r-- | sys/netinet/tcp_input.c | 11 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 59 | ||||
-rw-r--r-- | sys/netinet/tcp_timer.c | 6 | ||||
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 10 | ||||
-rw-r--r-- | sys/netinet/tcp_var.h | 6 |
5 files changed, 73 insertions, 19 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 8fc588e947f..75396e8974a 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.80 2000/12/11 08:04:55 itojun Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.81 2000/12/13 09:47:08 provos Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -1140,13 +1140,14 @@ findpcb: if (iss) tp->iss = iss; - else - tp->iss = tcp_iss; + else { #ifdef TCP_COMPAT_42 - tcp_iss += TCP_ISSINCR/2; + tcp_iss += TCP_ISSINCR/2; + tp->iss = tcp_iss; #else /* TCP_COMPAT_42 */ - tcp_iss += arc4random() % TCP_ISSINCR + 1; + tp->iss = tcp_rndiss_next(); #endif /* !TCP_COMPAT_42 */ + } tp->irs = th->th_seq; tcp_sendseqinit(tp); #if defined (TCP_SACK) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index e57ac20961c..9ab06da405c 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.36 2000/12/11 08:04:55 itojun Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.37 2000/12/13 09:47:08 provos Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -57,6 +57,8 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. #include <sys/socketvar.h> #include <sys/protosw.h> #include <sys/errno.h> +#include <sys/time.h> +#include <sys/kernel.h> #include <net/route.h> #include <net/if.h> @@ -137,9 +139,7 @@ tcp_init() { #ifdef TCP_COMPAT_42 tcp_iss = 1; /* wrong */ -#else /* TCP_COMPAT_42 */ - tcp_iss = arc4random() + 1; -#endif /* !TCP_COMPAT_42 */ +#endif /* TCP_COMPAT_42 */ in_pcbinit(&tcbtable, tcbhashsize); #ifdef INET6 @@ -1069,3 +1069,54 @@ tcp_signature_apply(fstate, data, len) return 0; } #endif /* TCP_SIGNATURE */ + +#define TCP_RNDISS_ROUNDS 16 +#define TCP_RNDISS_OUT 7200 +#define TCP_RNDISS_MAX 30000 + +u_int8_t tcp_rndiss_sbox[128]; +u_int16_t tcp_rndiss_msb; +u_int16_t tcp_rndiss_cnt; +long tcp_rndiss_reseed; + +u_int16_t +tcp_rndiss_encrypt(val) + u_int16_t val; +{ + u_int16_t sum = 0, i; + + for (i = 0; i < TCP_RNDISS_ROUNDS; i++) { + sum += 0x79b9; + val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7; + val = ((val & 0xff) << 7) | (val >> 8); + } + + return val; +} + +void +tcp_rndiss_init() +{ + get_random_bytes(tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox)); + + tcp_rndiss_reseed = time.tv_sec + TCP_RNDISS_OUT; + tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000; + tcp_rndiss_cnt = 0; +} + +tcp_seq +tcp_rndiss_next() +{ + u_int16_t tmp; + + if (tcp_rndiss_cnt >= TCP_RNDISS_MAX || + time.tv_sec > tcp_rndiss_reseed) + tcp_rndiss_init(); + + get_random_bytes(&tmp, sizeof(tmp)); + + /* (tmp & 0x7fff) ensures a 32768 byte gap between ISS */ + return ((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | tcp_rndiss_msb) <<16) | + (tmp & 0x7fff); +} + diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 9efd80756ca..4c300249da9 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_timer.c,v 1.19 2000/12/12 08:12:04 provos Exp $ */ +/* $OpenBSD: tcp_timer.c,v 1.20 2000/12/13 09:47:08 provos Exp $ */ /* $NetBSD: tcp_timer.c,v 1.14 1996/02/13 23:44:09 christos Exp $ */ /* @@ -144,9 +144,7 @@ tpgone: tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ if ((int)tcp_iss < 0) tcp_iss = 0; /* XXX */ -#else /* TCP_COMPAT_42 */ - tcp_iss += arc4random() % (2 * TCP_ISSINCR / PR_SLOWHZ) + 1; /* increment iss */ -#endif /* !TCP_COMPAT_42 */ +#endif /* TCP_COMPAT_42 */ tcp_now++; /* for timestamps */ splx(s); } diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 38a4fc02830..79942981ba2 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_usrreq.c,v 1.49 2000/12/11 08:04:56 itojun Exp $ */ +/* $OpenBSD: tcp_usrreq.c,v 1.50 2000/12/13 09:47:08 provos Exp $ */ /* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */ /* @@ -304,12 +304,12 @@ tcp_usrreq(so, req, m, nam, control) soisconnecting(so); tcpstat.tcps_connattempt++; tp->t_state = TCPS_SYN_SENT; - tp->t_timer[TCPT_KEEP] = tcptv_keep_init; - tp->iss = tcp_iss; + tp->t_timer[TCPT_KEEP] = tcptv_keep_init; #ifdef TCP_COMPAT_42 + tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2; -#else /* TCP_COMPAT_42 */ - tcp_iss += arc4random() % TCP_ISSINCR + 1; +#else /* TCP_COMPAT_42 */ + tp->iss = tcp_rndiss_next(); #endif /* !TCP_COMPAT_42 */ tcp_sendseqinit(tp); #if defined(TCP_SACK) diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index fa07feff32b..e5119a102fc 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_var.h,v 1.34 2000/12/11 08:04:56 itojun Exp $ */ +/* $OpenBSD: tcp_var.h,v 1.35 2000/12/13 09:47:08 provos Exp $ */ /* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */ /* @@ -401,5 +401,9 @@ u_long tcp_seq_subtract __P((u_long, u_long )); #ifdef TCP_SIGNATURE int tcp_signature_apply __P((caddr_t, caddr_t, unsigned int)); #endif /* TCP_SIGNATURE */ +void tcp_rndiss_init __P((void)); +tcp_seq tcp_rndiss_next __P((void)); +u_int16_t + tcp_rndiss_encrypt __P((u_int16_t)); #endif /* _KERNEL */ |