tcp: resalt the secret every 10 seconds
authorEric Dumazet <edumazet@google.com>
Mon, 2 May 2022 08:46:10 +0000 (10:46 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 5 May 2022 02:22:21 +0000 (19:22 -0700)
In order to limit the ability for an observer to recognize the source
ports sequence used to contact a set of destinations, we should
periodically shuffle the secret. 10 seconds looks effective enough
without causing particular issues.

Cc: Moshe Kol <moshe.kol@mail.huji.ac.il>
Cc: Yossi Gilad <yossi.gilad@mail.huji.ac.il>
Cc: Amit Klein <aksecurity@gmail.com>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/secure_seq.c

index 55aa5cc..5f85e01 100644 (file)
@@ -22,6 +22,8 @@
 static siphash_aligned_key_t net_secret;
 static siphash_aligned_key_t ts_secret;
 
+#define EPHEMERAL_PORT_SHUFFLE_PERIOD (10 * HZ)
+
 static __always_inline void net_secret_init(void)
 {
        net_get_random_once(&net_secret, sizeof(net_secret));
@@ -100,11 +102,13 @@ u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
        const struct {
                struct in6_addr saddr;
                struct in6_addr daddr;
+               unsigned int timeseed;
                __be16 dport;
        } __aligned(SIPHASH_ALIGNMENT) combined = {
                .saddr = *(struct in6_addr *)saddr,
                .daddr = *(struct in6_addr *)daddr,
-               .dport = dport
+               .timeseed = jiffies / EPHEMERAL_PORT_SHUFFLE_PERIOD,
+               .dport = dport,
        };
        net_secret_init();
        return siphash(&combined, offsetofend(typeof(combined), dport),
@@ -145,8 +149,10 @@ EXPORT_SYMBOL_GPL(secure_tcp_seq);
 u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
 {
        net_secret_init();
-       return siphash_3u32((__force u32)saddr, (__force u32)daddr,
-                           (__force u16)dport, &net_secret);
+       return siphash_4u32((__force u32)saddr, (__force u32)daddr,
+                           (__force u16)dport,
+                           jiffies / EPHEMERAL_PORT_SHUFFLE_PERIOD,
+                           &net_secret);
 }
 EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
 #endif