Blame view
net/core/secure_seq.c
4.88 KB
7cd23e530 secure_seq: use S... |
1 2 3 |
/* * Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ |
6e5714eaf net: Compute prot... |
4 5 6 7 8 9 10 11 12 |
#include <linux/kernel.h> #include <linux/init.h> #include <linux/cryptohash.h> #include <linux/module.h> #include <linux/cache.h> #include <linux/random.h> #include <linux/hrtimer.h> #include <linux/ktime.h> #include <linux/string.h> |
e34c9a699 net: switch net_s... |
13 |
#include <linux/net.h> |
7cd23e530 secure_seq: use S... |
14 |
#include <linux/siphash.h> |
6e5714eaf net: Compute prot... |
15 |
#include <net/secure_seq.h> |
cb03db9d0 net: secure_seq: ... |
16 |
#if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_INET) |
7cd23e530 secure_seq: use S... |
17 |
#include <linux/in6.h> |
25429d7b7 tcp: allow to tur... |
18 |
#include <net/tcp.h> |
6e5714eaf net: Compute prot... |
19 |
|
7cd23e530 secure_seq: use S... |
20 |
static siphash_key_t net_secret __read_mostly; |
28ee1b746 secure_seq: downg... |
21 |
static siphash_key_t ts_secret __read_mostly; |
9a3bab6b0 net: net_secret s... |
22 |
|
34d92d531 net: always inlin... |
23 |
static __always_inline void net_secret_init(void) |
6e5714eaf net: Compute prot... |
24 |
{ |
7cd23e530 secure_seq: use S... |
25 |
net_get_random_once(&net_secret, sizeof(net_secret)); |
6e5714eaf net: Compute prot... |
26 |
} |
84b114b98 tcp: randomize ti... |
27 28 29 30 31 |
static __always_inline void ts_secret_init(void) { net_get_random_once(&ts_secret, sizeof(ts_secret)); } |
cb03db9d0 net: secure_seq: ... |
32 |
#endif |
6e5714eaf net: Compute prot... |
33 |
|
681090902 net: Silence seq_... |
34 |
#ifdef CONFIG_INET |
6e5714eaf net: Compute prot... |
35 36 37 38 39 40 41 42 43 44 45 46 |
static u32 seq_scale(u32 seq) { /* * As close as possible to RFC 793, which * suggests using a 250 kHz clock. * Further reading shows this assumes 2 Mb/s networks. * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but * we also need to limit the resolution so that the u32 seq * overlaps less than one time per MSL (2 minutes). * Choosing a clock of 64 ns period is OK. (period of 274 s) */ |
d2de875c6 net: use ktime_ge... |
47 |
return seq + (ktime_get_real_ns() >> 6); |
6e5714eaf net: Compute prot... |
48 |
} |
681090902 net: Silence seq_... |
49 |
#endif |
6e5714eaf net: Compute prot... |
50 |
|
dfd56b8b3 net: use IS_ENABL... |
51 |
#if IS_ENABLED(CONFIG_IPV6) |
5d2ed0521 tcp: Namespaceify... |
52 53 |
u32 secure_tcpv6_ts_off(const struct net *net, const __be32 *saddr, const __be32 *daddr) |
28ee1b746 secure_seq: downg... |
54 55 56 57 58 59 60 61 |
{ const struct { struct in6_addr saddr; struct in6_addr daddr; } __aligned(SIPHASH_ALIGNMENT) combined = { .saddr = *(struct in6_addr *)saddr, .daddr = *(struct in6_addr *)daddr, }; |
5d2ed0521 tcp: Namespaceify... |
62 |
if (net->ipv4.sysctl_tcp_timestamps != 1) |
28ee1b746 secure_seq: downg... |
63 |
return 0; |
84b114b98 tcp: randomize ti... |
64 |
ts_secret_init(); |
28ee1b746 secure_seq: downg... |
65 66 67 |
return siphash(&combined, offsetofend(typeof(combined), daddr), &ts_secret); } |
84b114b98 tcp: randomize ti... |
68 |
EXPORT_SYMBOL(secure_tcpv6_ts_off); |
28ee1b746 secure_seq: downg... |
69 |
|
84b114b98 tcp: randomize ti... |
70 71 |
u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, __be16 sport, __be16 dport) |
6e5714eaf net: Compute prot... |
72 |
{ |
7cd23e530 secure_seq: use S... |
73 74 75 76 77 78 79 80 81 82 83 |
const struct { struct in6_addr saddr; struct in6_addr daddr; __be16 sport; __be16 dport; } __aligned(SIPHASH_ALIGNMENT) combined = { .saddr = *(struct in6_addr *)saddr, .daddr = *(struct in6_addr *)daddr, .sport = sport, .dport = dport }; |
84b114b98 tcp: randomize ti... |
84 |
u32 hash; |
9a3bab6b0 net: net_secret s... |
85 |
net_secret_init(); |
7cd23e530 secure_seq: use S... |
86 87 |
hash = siphash(&combined, offsetofend(typeof(combined), dport), &net_secret); |
7cd23e530 secure_seq: use S... |
88 |
return seq_scale(hash); |
6e5714eaf net: Compute prot... |
89 |
} |
84b114b98 tcp: randomize ti... |
90 |
EXPORT_SYMBOL(secure_tcpv6_seq); |
6e5714eaf net: Compute prot... |
91 92 93 94 |
u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport) { |
7cd23e530 secure_seq: use S... |
95 96 97 98 99 100 101 102 103 |
const struct { struct in6_addr saddr; struct in6_addr daddr; __be16 dport; } __aligned(SIPHASH_ALIGNMENT) combined = { .saddr = *(struct in6_addr *)saddr, .daddr = *(struct in6_addr *)daddr, .dport = dport }; |
9a3bab6b0 net: net_secret s... |
104 |
net_secret_init(); |
7cd23e530 secure_seq: use S... |
105 106 |
return siphash(&combined, offsetofend(typeof(combined), dport), &net_secret); |
6e5714eaf net: Compute prot... |
107 |
} |
58a317f10 netfilter: ipv6: ... |
108 |
EXPORT_SYMBOL(secure_ipv6_port_ephemeral); |
6e5714eaf net: Compute prot... |
109 110 111 |
#endif #ifdef CONFIG_INET |
5d2ed0521 tcp: Namespaceify... |
112 |
u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr) |
28ee1b746 secure_seq: downg... |
113 |
{ |
5d2ed0521 tcp: Namespaceify... |
114 |
if (net->ipv4.sysctl_tcp_timestamps != 1) |
28ee1b746 secure_seq: downg... |
115 |
return 0; |
84b114b98 tcp: randomize ti... |
116 |
ts_secret_init(); |
28ee1b746 secure_seq: downg... |
117 118 119 |
return siphash_2u32((__force u32)saddr, (__force u32)daddr, &ts_secret); } |
6e5714eaf net: Compute prot... |
120 |
|
a30aad50c tcp: rename *_seq... |
121 |
/* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d), |
7cd23e530 secure_seq: use S... |
122 123 124 125 |
* but fortunately, `sport' cannot be 0 in any circumstances. If this changes, * it would be easy enough to have the former function use siphash_4u32, passing * the arguments as separate u32. */ |
84b114b98 tcp: randomize ti... |
126 127 |
u32 secure_tcp_seq(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) |
6e5714eaf net: Compute prot... |
128 |
{ |
84b114b98 tcp: randomize ti... |
129 |
u32 hash; |
9a3bab6b0 net: net_secret s... |
130 |
net_secret_init(); |
7cd23e530 secure_seq: use S... |
131 132 133 |
hash = siphash_3u32((__force u32)saddr, (__force u32)daddr, (__force u32)sport << 16 | (__force u32)dport, &net_secret); |
7cd23e530 secure_seq: use S... |
134 |
return seq_scale(hash); |
6e5714eaf net: Compute prot... |
135 136 137 138 |
} u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) { |
9a3bab6b0 net: net_secret s... |
139 |
net_secret_init(); |
7cd23e530 secure_seq: use S... |
140 141 |
return siphash_3u32((__force u32)saddr, (__force u32)daddr, (__force u16)dport, &net_secret); |
6e5714eaf net: Compute prot... |
142 143 144 |
} EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); #endif |
a3bf7ae9a net:core: use IS_... |
145 |
#if IS_ENABLED(CONFIG_IP_DCCP) |
6e5714eaf net: Compute prot... |
146 147 148 |
u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) { |
6e5714eaf net: Compute prot... |
149 |
u64 seq; |
9a3bab6b0 net: net_secret s... |
150 |
net_secret_init(); |
c1ce1560a secure_seq: fix s... |
151 152 153 |
seq = siphash_3u32((__force u32)saddr, (__force u32)daddr, (__force u32)sport << 16 | (__force u32)dport, &net_secret); |
d2de875c6 net: use ktime_ge... |
154 |
seq += ktime_get_real_ns(); |
6e5714eaf net: Compute prot... |
155 |
seq &= (1ull << 48) - 1; |
6e5714eaf net: Compute prot... |
156 157 158 |
return seq; } EXPORT_SYMBOL(secure_dccp_sequence_number); |
dfd56b8b3 net: use IS_ENABL... |
159 |
#if IS_ENABLED(CONFIG_IPV6) |
6e5714eaf net: Compute prot... |
160 161 162 |
u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, __be16 sport, __be16 dport) { |
7cd23e530 secure_seq: use S... |
163 164 165 166 167 168 169 170 171 172 173 |
const struct { struct in6_addr saddr; struct in6_addr daddr; __be16 sport; __be16 dport; } __aligned(SIPHASH_ALIGNMENT) combined = { .saddr = *(struct in6_addr *)saddr, .daddr = *(struct in6_addr *)daddr, .sport = sport, .dport = dport }; |
6e5714eaf net: Compute prot... |
174 |
u64 seq; |
9a3bab6b0 net: net_secret s... |
175 |
net_secret_init(); |
7cd23e530 secure_seq: use S... |
176 177 |
seq = siphash(&combined, offsetofend(typeof(combined), dport), &net_secret); |
d2de875c6 net: use ktime_ge... |
178 |
seq += ktime_get_real_ns(); |
6e5714eaf net: Compute prot... |
179 |
seq &= (1ull << 48) - 1; |
6e5714eaf net: Compute prot... |
180 181 182 183 184 |
return seq; } EXPORT_SYMBOL(secure_dccpv6_sequence_number); #endif #endif |