1616#include <net/tcp.h>
1717#include <net/ipv6.h>
1818
19+ int tcp_ao_calc_traffic_key (struct tcp_ao_key * mkt , u8 * key , void * ctx ,
20+ unsigned int len , struct tcp_sigpool * hp )
21+ {
22+ struct scatterlist sg ;
23+ int ret ;
24+
25+ if (crypto_ahash_setkey (crypto_ahash_reqtfm (hp -> req ),
26+ mkt -> key , mkt -> keylen ))
27+ goto clear_hash ;
28+
29+ ret = crypto_ahash_init (hp -> req );
30+ if (ret )
31+ goto clear_hash ;
32+
33+ sg_init_one (& sg , ctx , len );
34+ ahash_request_set_crypt (hp -> req , & sg , key , len );
35+ crypto_ahash_update (hp -> req );
36+
37+ ret = crypto_ahash_final (hp -> req );
38+ if (ret )
39+ goto clear_hash ;
40+
41+ return 0 ;
42+ clear_hash :
43+ memset (key , 0 , tcp_ao_digest_size (mkt ));
44+ return 1 ;
45+ }
46+
1947/* Optimized version of tcp_ao_do_lookup(): only for sockets for which
2048 * it's known that the keys in ao_info are matching peer's
2149 * family/address/VRF/etc.
@@ -169,6 +197,71 @@ void tcp_ao_destroy_sock(struct sock *sk)
169197 kfree_rcu (ao , rcu );
170198}
171199
200+ /* 4 tuple and ISNs are expected in NBO */
201+ static int tcp_v4_ao_calc_key (struct tcp_ao_key * mkt , u8 * key ,
202+ __be32 saddr , __be32 daddr ,
203+ __be16 sport , __be16 dport ,
204+ __be32 sisn , __be32 disn )
205+ {
206+ /* See RFC5926 3.1.1 */
207+ struct kdf_input_block {
208+ u8 counter ;
209+ u8 label [6 ];
210+ struct tcp4_ao_context ctx ;
211+ __be16 outlen ;
212+ } __packed * tmp ;
213+ struct tcp_sigpool hp ;
214+ int err ;
215+
216+ err = tcp_sigpool_start (mkt -> tcp_sigpool_id , & hp );
217+ if (err )
218+ return err ;
219+
220+ tmp = hp .scratch ;
221+ tmp -> counter = 1 ;
222+ memcpy (tmp -> label , "TCP-AO" , 6 );
223+ tmp -> ctx .saddr = saddr ;
224+ tmp -> ctx .daddr = daddr ;
225+ tmp -> ctx .sport = sport ;
226+ tmp -> ctx .dport = dport ;
227+ tmp -> ctx .sisn = sisn ;
228+ tmp -> ctx .disn = disn ;
229+ tmp -> outlen = htons (tcp_ao_digest_size (mkt ) * 8 ); /* in bits */
230+
231+ err = tcp_ao_calc_traffic_key (mkt , key , tmp , sizeof (* tmp ), & hp );
232+ tcp_sigpool_end (& hp );
233+
234+ return err ;
235+ }
236+
237+ int tcp_v4_ao_calc_key_sk (struct tcp_ao_key * mkt , u8 * key ,
238+ const struct sock * sk ,
239+ __be32 sisn , __be32 disn , bool send )
240+ {
241+ if (send )
242+ return tcp_v4_ao_calc_key (mkt , key , sk -> sk_rcv_saddr ,
243+ sk -> sk_daddr , htons (sk -> sk_num ),
244+ sk -> sk_dport , sisn , disn );
245+ else
246+ return tcp_v4_ao_calc_key (mkt , key , sk -> sk_daddr ,
247+ sk -> sk_rcv_saddr , sk -> sk_dport ,
248+ htons (sk -> sk_num ), disn , sisn );
249+ }
250+
251+ static int tcp_ao_calc_key_sk (struct tcp_ao_key * mkt , u8 * key ,
252+ const struct sock * sk ,
253+ __be32 sisn , __be32 disn , bool send )
254+ {
255+ if (mkt -> family == AF_INET )
256+ return tcp_v4_ao_calc_key_sk (mkt , key , sk , sisn , disn , send );
257+ #if IS_ENABLED (CONFIG_IPV6 )
258+ else if (mkt -> family == AF_INET6 )
259+ return tcp_v6_ao_calc_key_sk (mkt , key , sk , sisn , disn , send );
260+ #endif
261+ else
262+ return - EOPNOTSUPP ;
263+ }
264+
172265struct tcp_ao_key * tcp_v4_ao_lookup (const struct sock * sk , struct sock * addr_sk ,
173266 int sndid , int rcvid )
174267{
@@ -177,6 +270,113 @@ struct tcp_ao_key *tcp_v4_ao_lookup(const struct sock *sk, struct sock *addr_sk,
177270 return tcp_ao_do_lookup (sk , addr , AF_INET , sndid , rcvid );
178271}
179272
273+ static int tcp_ao_cache_traffic_keys (const struct sock * sk ,
274+ struct tcp_ao_info * ao ,
275+ struct tcp_ao_key * ao_key )
276+ {
277+ u8 * traffic_key = snd_other_key (ao_key );
278+ int ret ;
279+
280+ ret = tcp_ao_calc_key_sk (ao_key , traffic_key , sk ,
281+ ao -> lisn , ao -> risn , true);
282+ if (ret )
283+ return ret ;
284+
285+ traffic_key = rcv_other_key (ao_key );
286+ ret = tcp_ao_calc_key_sk (ao_key , traffic_key , sk ,
287+ ao -> lisn , ao -> risn , false);
288+ return ret ;
289+ }
290+
291+ void tcp_ao_connect_init (struct sock * sk )
292+ {
293+ struct tcp_sock * tp = tcp_sk (sk );
294+ struct tcp_ao_info * ao_info ;
295+ union tcp_ao_addr * addr ;
296+ struct tcp_ao_key * key ;
297+ int family ;
298+
299+ ao_info = rcu_dereference_protected (tp -> ao_info ,
300+ lockdep_sock_is_held (sk ));
301+ if (!ao_info )
302+ return ;
303+
304+ /* Remove all keys that don't match the peer */
305+ family = sk -> sk_family ;
306+ if (family == AF_INET )
307+ addr = (union tcp_ao_addr * )& sk -> sk_daddr ;
308+ #if IS_ENABLED (CONFIG_IPV6 )
309+ else if (family == AF_INET6 )
310+ addr = (union tcp_ao_addr * )& sk -> sk_v6_daddr ;
311+ #endif
312+ else
313+ return ;
314+
315+ hlist_for_each_entry_rcu (key , & ao_info -> head , node ) {
316+ if (!tcp_ao_key_cmp (key , addr , key -> prefixlen , family , -1 , -1 ))
317+ continue ;
318+
319+ if (key == ao_info -> current_key )
320+ ao_info -> current_key = NULL ;
321+ if (key == ao_info -> rnext_key )
322+ ao_info -> rnext_key = NULL ;
323+ hlist_del_rcu (& key -> node );
324+ atomic_sub (tcp_ao_sizeof_key (key ), & sk -> sk_omem_alloc );
325+ call_rcu (& key -> rcu , tcp_ao_key_free_rcu );
326+ }
327+
328+ key = tp -> af_specific -> ao_lookup (sk , sk , -1 , -1 );
329+ if (key ) {
330+ /* if current_key or rnext_key were not provided,
331+ * use the first key matching the peer
332+ */
333+ if (!ao_info -> current_key )
334+ ao_info -> current_key = key ;
335+ if (!ao_info -> rnext_key )
336+ ao_info -> rnext_key = key ;
337+ tp -> tcp_header_len += tcp_ao_len (key );
338+
339+ ao_info -> lisn = htonl (tp -> write_seq );
340+ } else {
341+ /* Can't happen: tcp_connect() verifies that there's
342+ * at least one tcp-ao key that matches the remote peer.
343+ */
344+ WARN_ON_ONCE (1 );
345+ rcu_assign_pointer (tp -> ao_info , NULL );
346+ kfree (ao_info );
347+ }
348+ }
349+
350+ void tcp_ao_established (struct sock * sk )
351+ {
352+ struct tcp_ao_info * ao ;
353+ struct tcp_ao_key * key ;
354+
355+ ao = rcu_dereference_protected (tcp_sk (sk )-> ao_info ,
356+ lockdep_sock_is_held (sk ));
357+ if (!ao )
358+ return ;
359+
360+ hlist_for_each_entry_rcu (key , & ao -> head , node )
361+ tcp_ao_cache_traffic_keys (sk , ao , key );
362+ }
363+
364+ void tcp_ao_finish_connect (struct sock * sk , struct sk_buff * skb )
365+ {
366+ struct tcp_ao_info * ao ;
367+ struct tcp_ao_key * key ;
368+
369+ ao = rcu_dereference_protected (tcp_sk (sk )-> ao_info ,
370+ lockdep_sock_is_held (sk ));
371+ if (!ao )
372+ return ;
373+
374+ WRITE_ONCE (ao -> risn , tcp_hdr (skb )-> seq );
375+
376+ hlist_for_each_entry_rcu (key , & ao -> head , node )
377+ tcp_ao_cache_traffic_keys (sk , ao , key );
378+ }
379+
180380static bool tcp_ao_can_set_current_rnext (struct sock * sk )
181381{
182382 /* There aren't current/rnext keys on TCP_LISTEN sockets */
@@ -558,6 +758,12 @@ static int tcp_ao_add_cmd(struct sock *sk, unsigned short int family,
558758 if (ret < 0 )
559759 goto err_free_sock ;
560760
761+ /* Change this condition if we allow adding keys in states
762+ * like close_wait, syn_sent or fin_wait...
763+ */
764+ if (sk -> sk_state == TCP_ESTABLISHED )
765+ tcp_ao_cache_traffic_keys (sk , ao_info , key );
766+
561767 tcp_ao_link_mkt (ao_info , key );
562768 if (first ) {
563769 sk_gso_disable (sk );
0 commit comments