patch-2.3.37 linux/drivers/char/random.c
Next file: linux/drivers/char/raw.c
Previous file: linux/drivers/char/bttv.c
Back to the patch index
Back to the overall index
- Lines: 108
- Date:
Thu Jan 6 10:14:36 2000
- Orig file:
v2.3.36/linux/drivers/char/random.c
- Orig date:
Mon Oct 4 15:49:29 1999
diff -u --recursive --new-file v2.3.36/linux/drivers/char/random.c linux/drivers/char/random.c
@@ -1936,7 +1936,7 @@
/* Alternative: return sum of all words? */
}
-#if 0 /* May be needed for IPv6 */
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static __u32 twothirdsMD4Transform (__u32 const buf[4], __u32 const in[12])
{
@@ -2001,6 +2001,59 @@
#define REKEY_INTERVAL 300
#define HASH_BITS 24
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+__u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
+ __u16 sport, __u16 dport)
+{
+ static __u32 rekey_time = 0;
+ static __u32 count = 0;
+ static __u32 secret[12];
+ struct timeval tv;
+ __u32 seq;
+
+ /* The procedure is the same as for IPv4, but addresses are longer. */
+
+ do_gettimeofday(&tv); /* We need the usecs below... */
+
+ if (!rekey_time || (tv.tv_sec - rekey_time) > REKEY_INTERVAL) {
+ rekey_time = tv.tv_sec;
+ /* First five words are overwritten below. */
+ get_random_bytes(&secret[5], sizeof(secret)-5*4);
+ count = (tv.tv_sec/REKEY_INTERVAL) << HASH_BITS;
+ }
+
+ memcpy(secret, saddr, 16);
+ secret[4]=(sport << 16) + dport;
+
+ seq = (twothirdsMD4Transform(daddr, secret) &
+ ((1<<HASH_BITS)-1)) + count;
+
+ seq += tv.tv_usec + tv.tv_sec*1000000;
+ return seq;
+}
+
+__u32 secure_ipv6_id(__u32 *daddr)
+{
+ static time_t rekey_time = 0;
+ static __u32 secret[12];
+ time_t t;
+
+ /*
+ * Pick a random secret every REKEY_INTERVAL seconds.
+ */
+ t = CURRENT_TIME;
+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
+ rekey_time = t;
+ /* First word is overwritten below. */
+ get_random_bytes(secret, sizeof(secret));
+ }
+
+ return twothirdsMD4Transform(daddr, secret);
+}
+
+#endif
+
+
__u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
__u16 sport, __u16 dport)
{
@@ -2052,6 +2105,38 @@
saddr, daddr, sport, dport, seq);
#endif
return seq;
+}
+
+/* The code below is shamelessly stolen from secure_tcp_sequence_number().
+ * All blames to Andrey V. Savochkin <saw@msu.ru>.
+ */
+__u32 secure_ip_id(__u32 daddr)
+{
+ static time_t rekey_time = 0;
+ static __u32 secret[12];
+ time_t t;
+
+ /*
+ * Pick a random secret every REKEY_INTERVAL seconds.
+ */
+ t = CURRENT_TIME;
+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
+ rekey_time = t;
+ /* First word is overwritten below. */
+ get_random_bytes(secret+1, sizeof(secret)-4);
+ }
+
+ /*
+ * Pick a unique starting offset for each IP destination.
+ * Note that the words are placed into the first words to be
+ * mixed in with the halfMD4. This is because the starting
+ * vector is also a random secret (at secret+8), and further
+ * hashing fixed data into it isn't going to improve anything,
+ * so we should get started with the variable data.
+ */
+ secret[0]=daddr;
+
+ return halfMD4Transform(secret+8, secret);
}
#ifdef CONFIG_SYN_COOKIES
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)