1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _TCP_AO_H
3 #define _TCP_AO_H
4
5 #define TCP_AO_KEY_ALIGN 1
6 #define __tcp_ao_key_align __aligned(TCP_AO_KEY_ALIGN)
7
8 union tcp_ao_addr {
9 struct in_addr a4;
10 #if IS_ENABLED(CONFIG_IPV6)
11 struct in6_addr a6;
12 #endif
13 };
14
15 struct tcp_ao_hdr {
16 u8 kind;
17 u8 length;
18 u8 keyid;
19 u8 rnext_keyid;
20 };
21
tcp_ao_hdr_maclen(const struct tcp_ao_hdr * aoh)22 static inline u8 tcp_ao_hdr_maclen(const struct tcp_ao_hdr *aoh)
23 {
24 return aoh->length - sizeof(struct tcp_ao_hdr);
25 }
26
27 struct tcp_ao_counters {
28 atomic64_t pkt_good;
29 atomic64_t pkt_bad;
30 atomic64_t key_not_found;
31 atomic64_t ao_required;
32 atomic64_t dropped_icmp;
33 };
34
35 struct tcp_ao_key {
36 struct hlist_node node;
37 union tcp_ao_addr addr;
38 u8 key[TCP_AO_MAXKEYLEN] __tcp_ao_key_align;
39 unsigned int tcp_sigpool_id;
40 unsigned int digest_size;
41 int l3index;
42 u8 prefixlen;
43 u8 family;
44 u8 keylen;
45 u8 keyflags;
46 u8 sndid;
47 u8 rcvid;
48 u8 maclen;
49 struct rcu_head rcu;
50 atomic64_t pkt_good;
51 atomic64_t pkt_bad;
52 u8 traffic_keys[];
53 };
54
rcv_other_key(struct tcp_ao_key * key)55 static inline u8 *rcv_other_key(struct tcp_ao_key *key)
56 {
57 return key->traffic_keys;
58 }
59
snd_other_key(struct tcp_ao_key * key)60 static inline u8 *snd_other_key(struct tcp_ao_key *key)
61 {
62 return key->traffic_keys + key->digest_size;
63 }
64
tcp_ao_maclen(const struct tcp_ao_key * key)65 static inline int tcp_ao_maclen(const struct tcp_ao_key *key)
66 {
67 return key->maclen;
68 }
69
70 /* Use tcp_ao_len_aligned() for TCP header calculations */
tcp_ao_len(const struct tcp_ao_key * key)71 static inline int tcp_ao_len(const struct tcp_ao_key *key)
72 {
73 return tcp_ao_maclen(key) + sizeof(struct tcp_ao_hdr);
74 }
75
tcp_ao_len_aligned(const struct tcp_ao_key * key)76 static inline int tcp_ao_len_aligned(const struct tcp_ao_key *key)
77 {
78 return round_up(tcp_ao_len(key), 4);
79 }
80
tcp_ao_digest_size(struct tcp_ao_key * key)81 static inline unsigned int tcp_ao_digest_size(struct tcp_ao_key *key)
82 {
83 return key->digest_size;
84 }
85
tcp_ao_sizeof_key(const struct tcp_ao_key * key)86 static inline int tcp_ao_sizeof_key(const struct tcp_ao_key *key)
87 {
88 return sizeof(struct tcp_ao_key) + (key->digest_size << 1);
89 }
90
91 struct tcp_ao_info {
92 /* List of tcp_ao_key's */
93 struct hlist_head head;
94 /* current_key and rnext_key are maintained on sockets
95 * in TCP_AO_ESTABLISHED states.
96 * Their purpose is to cache keys on established connections,
97 * saving needless lookups. Never dereference any of them from
98 * listen sockets.
99 * ::current_key may change in RX to the key that was requested by
100 * the peer, please use READ_ONCE()/WRITE_ONCE() in order to avoid
101 * load/store tearing.
102 * Do the same for ::rnext_key, if you don't hold socket lock
103 * (it's changed only by userspace request in setsockopt()).
104 */
105 struct tcp_ao_key *current_key;
106 struct tcp_ao_key *rnext_key;
107 struct tcp_ao_counters counters;
108 u32 ao_required :1,
109 accept_icmps :1,
110 __unused :30;
111 __be32 lisn;
112 __be32 risn;
113 /* Sequence Number Extension (SNE) are upper 4 bytes for SEQ,
114 * that protect TCP-AO connection from replayed old TCP segments.
115 * See RFC5925 (6.2).
116 * In order to get correct SNE, there's a helper tcp_ao_compute_sne().
117 * It needs SEQ basis to understand whereabouts are lower SEQ numbers.
118 * According to that basis vector, it can provide incremented SNE
119 * when SEQ rolls over or provide decremented SNE when there's
120 * a retransmitted segment from before-rolling over.
121 * - for request sockets such basis is rcv_isn/snt_isn, which seems
122 * good enough as it's unexpected to receive 4 Gbytes on reqsk.
123 * - for full sockets the basis is rcv_nxt/snd_una. snd_una is
124 * taken instead of snd_nxt as currently it's easier to track
125 * in tcp_snd_una_update(), rather than updating SNE in all
126 * WRITE_ONCE(tp->snd_nxt, ...)
127 * - for time-wait sockets the basis is tw_rcv_nxt/tw_snd_nxt.
128 * tw_snd_nxt is not expected to change, while tw_rcv_nxt may.
129 */
130 u32 snd_sne;
131 u32 rcv_sne;
132 refcount_t refcnt; /* Protects twsk destruction */
133 struct rcu_head rcu;
134 };
135
136 #ifdef CONFIG_TCP_MD5SIG
137 #include <linux/jump_label.h>
138 extern struct static_key_false_deferred tcp_md5_needed;
139 #define static_branch_tcp_md5() static_branch_unlikely(&tcp_md5_needed.key)
140 #else
141 #define static_branch_tcp_md5() false
142 #endif
143 #ifdef CONFIG_TCP_AO
144 /* TCP-AO structures and functions */
145 #include <linux/jump_label.h>
146 extern struct static_key_false_deferred tcp_ao_needed;
147 #define static_branch_tcp_ao() static_branch_unlikely(&tcp_ao_needed.key)
148 #else
149 #define static_branch_tcp_ao() false
150 #endif
151
152 #ifdef CONFIG_TCP_AO
153 /* TCP-AO structures and functions */
154 struct tcp4_ao_context {
155 __be32 saddr;
156 __be32 daddr;
157 __be16 sport;
158 __be16 dport;
159 __be32 sisn;
160 __be32 disn;
161 };
162
163 struct tcp6_ao_context {
164 struct in6_addr saddr;
165 struct in6_addr daddr;
166 __be16 sport;
167 __be16 dport;
168 __be32 sisn;
169 __be32 disn;
170 };
171
172 struct tcp_sigpool;
173 /* Established states are fast-path and there always is current_key/rnext_key */
174 #define TCP_AO_ESTABLISHED (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | \
175 TCPF_CLOSE_WAIT | TCPF_LAST_ACK | TCPF_CLOSING)
176
177 int tcp_ao_transmit_skb(struct sock *sk, struct sk_buff *skb,
178 struct tcp_ao_key *key, struct tcphdr *th,
179 __u8 *hash_location);
180 int tcp_ao_hash_skb(unsigned short int family,
181 char *ao_hash, struct tcp_ao_key *key,
182 const struct sock *sk, const struct sk_buff *skb,
183 const u8 *tkey, int hash_offset, u32 sne);
184 int tcp_parse_ao(struct sock *sk, int cmd, unsigned short int family,
185 sockptr_t optval, int optlen);
186 struct tcp_ao_key *tcp_ao_established_key(struct tcp_ao_info *ao,
187 int sndid, int rcvid);
188 int tcp_ao_copy_all_matching(const struct sock *sk, struct sock *newsk,
189 struct request_sock *req, struct sk_buff *skb,
190 int family);
191 int tcp_ao_calc_traffic_key(struct tcp_ao_key *mkt, u8 *key, void *ctx,
192 unsigned int len, struct tcp_sigpool *hp);
193 void tcp_ao_destroy_sock(struct sock *sk, bool twsk);
194 void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw, struct tcp_sock *tp);
195 bool tcp_ao_ignore_icmp(const struct sock *sk, int family, int type, int code);
196 int tcp_ao_get_mkts(struct sock *sk, sockptr_t optval, sockptr_t optlen);
197 int tcp_ao_get_sock_info(struct sock *sk, sockptr_t optval, sockptr_t optlen);
198 int tcp_ao_get_repair(struct sock *sk, sockptr_t optval, sockptr_t optlen);
199 int tcp_ao_set_repair(struct sock *sk, sockptr_t optval, unsigned int optlen);
200 enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk,
201 const struct sk_buff *skb, unsigned short int family,
202 const struct request_sock *req, int l3index,
203 const struct tcp_ao_hdr *aoh);
204 u32 tcp_ao_compute_sne(u32 next_sne, u32 next_seq, u32 seq);
205 struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk, int l3index,
206 const union tcp_ao_addr *addr,
207 int family, int sndid, int rcvid);
208 int tcp_ao_hash_hdr(unsigned short family, char *ao_hash,
209 struct tcp_ao_key *key, const u8 *tkey,
210 const union tcp_ao_addr *daddr,
211 const union tcp_ao_addr *saddr,
212 const struct tcphdr *th, u32 sne);
213 int tcp_ao_prepare_reset(const struct sock *sk, struct sk_buff *skb,
214 const struct tcp_ao_hdr *aoh, int l3index, u32 seq,
215 struct tcp_ao_key **key, char **traffic_key,
216 bool *allocated_traffic_key, u8 *keyid, u32 *sne);
217
218 /* ipv4 specific functions */
219 int tcp_v4_parse_ao(struct sock *sk, int cmd, sockptr_t optval, int optlen);
220 struct tcp_ao_key *tcp_v4_ao_lookup(const struct sock *sk, struct sock *addr_sk,
221 int sndid, int rcvid);
222 int tcp_v4_ao_synack_hash(char *ao_hash, struct tcp_ao_key *mkt,
223 struct request_sock *req, const struct sk_buff *skb,
224 int hash_offset, u32 sne);
225 int tcp_v4_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key,
226 const struct sock *sk,
227 __be32 sisn, __be32 disn, bool send);
228 int tcp_v4_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key,
229 struct request_sock *req);
230 struct tcp_ao_key *tcp_v4_ao_lookup_rsk(const struct sock *sk,
231 struct request_sock *req,
232 int sndid, int rcvid);
233 int tcp_v4_ao_hash_skb(char *ao_hash, struct tcp_ao_key *key,
234 const struct sock *sk, const struct sk_buff *skb,
235 const u8 *tkey, int hash_offset, u32 sne);
236 /* ipv6 specific functions */
237 int tcp_v6_ao_hash_pseudoheader(struct tcp_sigpool *hp,
238 const struct in6_addr *daddr,
239 const struct in6_addr *saddr, int nbytes);
240 int tcp_v6_ao_calc_key_skb(struct tcp_ao_key *mkt, u8 *key,
241 const struct sk_buff *skb, __be32 sisn, __be32 disn);
242 int tcp_v6_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key,
243 const struct sock *sk, __be32 sisn,
244 __be32 disn, bool send);
245 int tcp_v6_ao_calc_key_rsk(struct tcp_ao_key *mkt, u8 *key,
246 struct request_sock *req);
247 struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk,
248 struct sock *addr_sk, int sndid, int rcvid);
249 struct tcp_ao_key *tcp_v6_ao_lookup_rsk(const struct sock *sk,
250 struct request_sock *req,
251 int sndid, int rcvid);
252 int tcp_v6_ao_hash_skb(char *ao_hash, struct tcp_ao_key *key,
253 const struct sock *sk, const struct sk_buff *skb,
254 const u8 *tkey, int hash_offset, u32 sne);
255 int tcp_v6_parse_ao(struct sock *sk, int cmd, sockptr_t optval, int optlen);
256 int tcp_v6_ao_synack_hash(char *ao_hash, struct tcp_ao_key *ao_key,
257 struct request_sock *req, const struct sk_buff *skb,
258 int hash_offset, u32 sne);
259 void tcp_ao_established(struct sock *sk);
260 void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb);
261 void tcp_ao_connect_init(struct sock *sk);
262 void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb,
263 struct request_sock *req, unsigned short int family);
264 #else /* CONFIG_TCP_AO */
265
tcp_ao_transmit_skb(struct sock * sk,struct sk_buff * skb,struct tcp_ao_key * key,struct tcphdr * th,__u8 * hash_location)266 static inline int tcp_ao_transmit_skb(struct sock *sk, struct sk_buff *skb,
267 struct tcp_ao_key *key, struct tcphdr *th,
268 __u8 *hash_location)
269 {
270 return 0;
271 }
272
tcp_ao_syncookie(struct sock * sk,const struct sk_buff * skb,struct request_sock * req,unsigned short int family)273 static inline void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb,
274 struct request_sock *req, unsigned short int family)
275 {
276 }
277
tcp_ao_ignore_icmp(const struct sock * sk,int family,int type,int code)278 static inline bool tcp_ao_ignore_icmp(const struct sock *sk, int family,
279 int type, int code)
280 {
281 return false;
282 }
283
tcp_inbound_ao_hash(struct sock * sk,const struct sk_buff * skb,unsigned short int family,const struct request_sock * req,int l3index,const struct tcp_ao_hdr * aoh)284 static inline enum skb_drop_reason tcp_inbound_ao_hash(struct sock *sk,
285 const struct sk_buff *skb, unsigned short int family,
286 const struct request_sock *req, int l3index,
287 const struct tcp_ao_hdr *aoh)
288 {
289 return SKB_NOT_DROPPED_YET;
290 }
291
tcp_ao_do_lookup(const struct sock * sk,int l3index,const union tcp_ao_addr * addr,int family,int sndid,int rcvid)292 static inline struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk,
293 int l3index, const union tcp_ao_addr *addr,
294 int family, int sndid, int rcvid)
295 {
296 return NULL;
297 }
298
tcp_ao_destroy_sock(struct sock * sk,bool twsk)299 static inline void tcp_ao_destroy_sock(struct sock *sk, bool twsk)
300 {
301 }
302
tcp_ao_established(struct sock * sk)303 static inline void tcp_ao_established(struct sock *sk)
304 {
305 }
306
tcp_ao_finish_connect(struct sock * sk,struct sk_buff * skb)307 static inline void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb)
308 {
309 }
310
tcp_ao_time_wait(struct tcp_timewait_sock * tcptw,struct tcp_sock * tp)311 static inline void tcp_ao_time_wait(struct tcp_timewait_sock *tcptw,
312 struct tcp_sock *tp)
313 {
314 }
315
tcp_ao_connect_init(struct sock * sk)316 static inline void tcp_ao_connect_init(struct sock *sk)
317 {
318 }
319
tcp_ao_get_mkts(struct sock * sk,sockptr_t optval,sockptr_t optlen)320 static inline int tcp_ao_get_mkts(struct sock *sk, sockptr_t optval, sockptr_t optlen)
321 {
322 return -ENOPROTOOPT;
323 }
324
tcp_ao_get_sock_info(struct sock * sk,sockptr_t optval,sockptr_t optlen)325 static inline int tcp_ao_get_sock_info(struct sock *sk, sockptr_t optval, sockptr_t optlen)
326 {
327 return -ENOPROTOOPT;
328 }
329
tcp_ao_get_repair(struct sock * sk,sockptr_t optval,sockptr_t optlen)330 static inline int tcp_ao_get_repair(struct sock *sk,
331 sockptr_t optval, sockptr_t optlen)
332 {
333 return -ENOPROTOOPT;
334 }
335
tcp_ao_set_repair(struct sock * sk,sockptr_t optval,unsigned int optlen)336 static inline int tcp_ao_set_repair(struct sock *sk,
337 sockptr_t optval, unsigned int optlen)
338 {
339 return -ENOPROTOOPT;
340 }
341 #endif
342
343 #if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
344 int tcp_do_parse_auth_options(const struct tcphdr *th,
345 const u8 **md5_hash, const u8 **ao_hash);
346 #else
tcp_do_parse_auth_options(const struct tcphdr * th,const u8 ** md5_hash,const u8 ** ao_hash)347 static inline int tcp_do_parse_auth_options(const struct tcphdr *th,
348 const u8 **md5_hash, const u8 **ao_hash)
349 {
350 *md5_hash = NULL;
351 *ao_hash = NULL;
352 return 0;
353 }
354 #endif
355
356 #endif /* _TCP_AO_H */
357