diff -Nur linux-2.6.11-rc2/include/linux/random.h linux-2.6.11-rc2.tx1/include/linux/random.h --- linux-2.6.11-rc2/include/linux/random.h 2005-01-26 19:54:17.000000000 +0100 +++ linux-2.6.11-rc2.tx1/include/linux/random.h 2005-01-28 19:45:31.359923392 +0100 @@ -42,6 +42,12 @@ #ifdef __KERNEL__ +/* OpenBSD Networking-related randomization functions - lorenzo@gnu.org */ +extern unsigned long obsd_get_random_long(void); +extern __u16 ip_randomid(void); +extern __u32 ip_randomisn(void); + + extern void rand_initialize_irq(int irq); extern void add_input_randomness(unsigned int type, unsigned int code, diff -Nur linux-2.6.11-rc2/net/ipv4/tcp_ipv4.c linux-2.6.11-rc2.tx1/net/ipv4/tcp_ipv4.c --- linux-2.6.11-rc2/net/ipv4/tcp_ipv4.c 2005-01-26 19:54:19.000000000 +0100 +++ linux-2.6.11-rc2.tx1/net/ipv4/tcp_ipv4.c 2005-01-28 19:39:48.000000000 +0100 @@ -539,10 +539,8 @@ static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) { - return secure_tcp_sequence_number(skb->nh.iph->daddr, - skb->nh.iph->saddr, - skb->h.th->dest, - skb->h.th->source); + + return ip_randomisn(); } /* called with local bh disabled */ @@ -833,14 +831,11 @@ tcp_v4_setup_caps(sk, &rt->u.dst); tp->ext2_header_len = rt->u.dst.header_len; - if (!tp->write_seq) - tp->write_seq = secure_tcp_sequence_number(inet->saddr, - inet->daddr, - inet->sport, - usin->sin_port); - - inet->id = tp->write_seq ^ jiffies; - + if (!tp->write_seq) { + tp->write_seq = ip_randomisn(); + } + + inet->id = htons(ip_randomid()); err = tcp_connect(sk); rt = NULL; if (err) @@ -1579,8 +1574,8 @@ if (newinet->opt) newtp->ext_header_len = newinet->opt->optlen; newtp->ext2_header_len = dst->header_len; - newinet->id = newtp->write_seq ^ jiffies; - + newinet->id = htons(ip_randomid()); + tcp_sync_mss(newsk, dst_pmtu(dst)); newtp->advmss = dst_metric(dst, RTAX_ADVMSS); tcp_initialize_rcv_mss(newsk); diff -Nur linux-2.6.11-rc2/net/Makefile linux-2.6.11-rc2.tx1/net/Makefile --- linux-2.6.11-rc2/net/Makefile 2005-01-26 19:50:49.000000000 +0100 +++ linux-2.6.11-rc2.tx1/net/Makefile 2005-01-28 21:01:21.870140688 +0100 @@ -11,6 +11,7 @@ tmp-$(CONFIG_COMPAT) := compat.o obj-$(CONFIG_NET) += $(tmp-y) +obj-y += obsd_rand.o # LLC has to be linked before the files in net/802/ obj-$(CONFIG_LLC) += llc/ diff -Nur linux-2.6.11-rc2/net/obsd_rand.c linux-2.6.11-rc2.tx1/net/obsd_rand.c --- linux-2.6.11-rc2/net/obsd_rand.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.11-rc2.tx1/net/obsd_rand.c 2005-01-28 17:43:50.000000000 +0100 @@ -0,0 +1,269 @@ +/* $Id: openbsd-netrand-2.6.11-rc2.patch,v 1.5 2005/01/28 20:16:21 lorenzo Exp $ + * Copyright (c) 2005 Lorenzo Hernandez Garcia-Hierro . + * All rights reserved. + * + * Added some macros and stolen code from random.c, for individual and less + * "invasive" implementation.Also removed the get_random_long() macro definition, + * which is not good if we can simply call back obsd_get_random_long(). + * + * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff. + * + * Version 1.90, last modified 28-Jan-05 + * + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. + * All rights reserved. + * + * Copyright 1998 Niels Provos + * All rights reserved. + * Theo de Raadt came up with the idea of using + * such a mathematical system to generate more random (yet non-repeating) + * ids to solve the resolver/named problem. But Niels designed the + * actual system based on the constraints. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#define RU_OUT 180 +#define RU_MAX 30000 +#define RU_GEN 2 +#define RU_N 32749 +#define RU_AGEN 7 +#define RU_M 31104 +#define PFAC_N 3 + +/* + * Stolen from ./drivers/char/random.c + */ + +/* FOO, GEEK and HECK are basic geekish MD4 functions: foo selection, geek majority, heck parity */ +#define FOO(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define GEEK(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) +#define HECK(x, y, z) ((x) ^ (y) ^ (z)) +#define OBROUND(f, a, b, c, d, x, s) \ + (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s))) +#define obK1 0 +#define obK2 013240474631UL +#define obK3 015666365641UL +#define OB_REKEY_INTERVAL (300 * HZ) + + +const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 }; + +static __u16 ru_x; +static __u16 ru_seed, ru_seed2; +static __u16 ru_a, ru_b; +static __u16 ru_g; +static __u16 ru_counter = 0; +static __u16 ru_msb = 0; +static unsigned long ru_reseed = 0; +static __u32 tmp; + +#define TCP_RNDISS_ROUNDS 15 +#define TCP_RNDISS_OUT 7200 +#define TCP_RNDISS_MAX 30000 + +static __u8 tcp_rndiss_sbox[128]; +static __u16 tcp_rndiss_msb; +static __u16 tcp_rndiss_cnt; +static unsigned long tcp_rndiss_reseed; + +static __u16 pmod(__u16, __u16, __u16); +static void ip_initid(void); +__u16 ip_randomid(void); + +/* + * Basic cut-down MD4 transform. Returns only 32 bits of result. + */ +static __u32 half_md4_transform (__u32 const buf[4], __u32 const in[8]) +{ + __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ + OBROUND(FOO, a, b, c, d, in[0] + obK1, 3); + OBROUND(FOO, d, a, b, c, in[1] + obK1, 7); + OBROUND(FOO, c, d, a, b, in[2] + obK1, 11); + OBROUND(FOO, b, c, d, a, in[3] + obK1, 19); + OBROUND(FOO, a, b, c, d, in[4] + obK1, 3); + OBROUND(FOO, d, a, b, c, in[5] + obK1, 7); + OBROUND(FOO, c, d, a, b, in[6] + obK1, 11); + OBROUND(FOO, b, c, d, a, in[7] + obK1, 19); + + /* Round 2 */ + OBROUND(GEEK, a, b, c, d, in[1] + obK2, 3); + OBROUND(GEEK, d, a, b, c, in[3] + obK2, 5); + OBROUND(GEEK, c, d, a, b, in[5] + obK2, 9); + OBROUND(GEEK, b, c, d, a, in[7] + obK2, 13); + OBROUND(GEEK, a, b, c, d, in[0] + obK2, 3); + OBROUND(GEEK, d, a, b, c, in[2] + obK2, 5); + OBROUND(GEEK, c, d, a, b, in[4] + obK2, 9); + OBROUND(GEEK, b, c, d, a, in[6] + obK2, 13); + + /* Round 3 */ + OBROUND(HECK, a, b, c, d, in[3] + obK3, 3); + OBROUND(HECK, d, a, b, c, in[7] + obK3, 9); + OBROUND(HECK, c, d, a, b, in[2] + obK3, 11); + OBROUND(HECK, b, c, d, a, in[6] + obK3, 15); + OBROUND(HECK, a, b, c, d, in[1] + obK3, 3); + OBROUND(HECK, d, a, b, c, in[5] + obK3, 9); + OBROUND(HECK, c, d, a, b, in[0] + obK3, 11); + OBROUND(HECK, b, c, d, a, in[4] + obK3, 15); + + return buf[1] + b; /* "most hashed" word */ + /* Alternative: return sum of all words? */ +} + +unsigned long obsd_get_random_long(void) +{ + static time_t rekey_time; + static __u32 secret[12]; + time_t t; + + /* + * Pick a random secret every OB_REKEY_INTERVAL seconds. + */ + t = get_seconds(); + if (!rekey_time || (t - rekey_time) > OB_REKEY_INTERVAL) { + rekey_time = t; + get_random_bytes(secret, sizeof(secret)); + } + + secret[1] = half_md4_transform(secret+8, secret); + secret[0] = half_md4_transform(secret+8, secret); + return *(unsigned long *)secret; +} + +static __u16 +pmod(__u16 gen, __u16 exp, __u16 mod) +{ + __u16 s, t, u; + + s = 1; + t = gen; + u = exp; + + while (u) { + if (u & 1) + s = (s * t) % mod; + u >>= 1; + t = (t * t) % mod; + } + return (s); +} + +static void +ip_initid(void) +{ + __u16 j, i; + int noprime = 1; + + ru_x = ((tmp = obsd_get_random_long()) & 0xFFFF) % RU_M; + + ru_seed = (tmp >> 16) & 0x7FFF; + ru_seed2 = obsd_get_random_long() & 0x7FFF; + + ru_b = ((tmp = obsd_get_random_long()) & 0xfffe) | 1; + ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M); + while (ru_b % 3 == 0) + ru_b += 2; + + j = (tmp = obsd_get_random_long()) % RU_N; + tmp = tmp >> 16; + + while (noprime) { + for (i = 0; i < PFAC_N; i++) + if (j % pfacts[i] == 0) + break; + + if (i >= PFAC_N) + noprime = 0; + else + j = (j + 1) % RU_N; + } + + ru_g = pmod(RU_GEN, j, RU_N); + ru_counter = 0; + + ru_reseed = xtime.tv_sec + RU_OUT; + ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; +} + +__u16 +ip_randomid(void) +{ + int i, n; + + if (ru_counter >= RU_MAX || time_after(get_seconds(), ru_reseed)) + ip_initid(); + + if (!tmp) + tmp = obsd_get_random_long(); + + n = tmp & 0x3; + tmp = tmp >> 2; + if (ru_counter + n >= RU_MAX) + ip_initid(); + for (i = 0; i <= n; i++) + ru_x = (ru_a * ru_x + ru_b) % RU_M; + ru_counter += i; + + return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb); +} + +static __u16 +tcp_rndiss_encrypt(__u16 val) +{ + __u16 sum = 0, i; + + for (i = 0; i < TCP_RNDISS_ROUNDS; i++) { + sum += 0x79b9; + val ^= ((__u16) tcp_rndiss_sbox[(val ^ sum) & 0x7f]) << 7; + val = ((val & 0xff) << 7) | (val >> 8); + } + + return val; +} + +static void +tcp_rndiss_init(void) +{ + get_random_bytes(tcp_rndiss_sbox, sizeof (tcp_rndiss_sbox)); + tcp_rndiss_reseed = get_seconds() + TCP_RNDISS_OUT; + tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000; + tcp_rndiss_cnt = 0; +} + +__u32 +ip_randomisn(void) +{ + if (tcp_rndiss_cnt >= TCP_RNDISS_MAX || + time_after(get_seconds(), tcp_rndiss_reseed)) + tcp_rndiss_init(); + + return (((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | + tcp_rndiss_msb) << 16) | (obsd_get_random_long() & 0x7fff)); +} diff -Nur linux-2.6.11-rc2/net/sunrpc/xprt.c linux-2.6.11-rc2.tx1/net/sunrpc/xprt.c --- linux-2.6.11-rc2/net/sunrpc/xprt.c 2005-01-26 19:54:20.000000000 +0100 +++ linux-2.6.11-rc2.tx1/net/sunrpc/xprt.c 2005-01-28 19:42:46.000000000 +0100 @@ -1342,7 +1342,9 @@ */ static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt) { - return xprt->xid++; + /* Return randomized xprt->xid instead of prt->xid++ */ + return (u32) obsd_get_random_long(); + } static inline void xprt_init_xid(struct rpc_xprt *xprt)