Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/tcp: Add TCP-AO config and structures

Introduce new kernel config option and common structures as well as
helpers to be used by TCP-AO code.

Co-developed-by: Francesco Ruggeri <fruggeri@arista.com>
Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
Co-developed-by: Salam Noureddine <noureddine@arista.com>
Signed-off-by: Salam Noureddine <noureddine@arista.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Acked-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Dmitry Safonov and committed by
David S. Miller
c845f5f3 8c73b263

+114 -8
+7 -2
include/linux/tcp.h
··· 447 447 bool syn_smc; /* SYN includes SMC */ 448 448 #endif 449 449 450 - #ifdef CONFIG_TCP_MD5SIG 451 - /* TCP AF-Specific parts; only used by MD5 Signature support so far */ 450 + #if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO) 451 + /* TCP AF-Specific parts; only used by TCP-AO/MD5 Signature support so far */ 452 452 const struct tcp_sock_af_ops *af_specific; 453 453 454 + #ifdef CONFIG_TCP_MD5SIG 454 455 /* TCP MD5 Signature Option information */ 455 456 struct tcp_md5sig_info __rcu *md5sig_info; 457 + #endif 458 + #ifdef CONFIG_TCP_AO 459 + struct tcp_ao_info __rcu *ao_info; 460 + #endif 456 461 #endif 457 462 458 463 /* TCP fastopen related information */
+2 -6
include/net/tcp.h
··· 37 37 #include <net/snmp.h> 38 38 #include <net/ip.h> 39 39 #include <net/tcp_states.h> 40 + #include <net/tcp_ao.h> 40 41 #include <net/inet_ecn.h> 41 42 #include <net/dst.h> 42 43 #include <net/mptcp.h> ··· 1689 1688 tp->retransmit_skb_hint = NULL; 1690 1689 } 1691 1690 1692 - union tcp_md5_addr { 1693 - struct in_addr a4; 1694 - #if IS_ENABLED(CONFIG_IPV6) 1695 - struct in6_addr a6; 1696 - #endif 1697 - }; 1691 + #define tcp_md5_addr tcp_ao_addr 1698 1692 1699 1693 /* - key database */ 1700 1694 struct tcp_md5sig_key {
+90
include/net/tcp_ao.h
··· 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 + 22 + struct tcp_ao_key { 23 + struct hlist_node node; 24 + union tcp_ao_addr addr; 25 + u8 key[TCP_AO_MAXKEYLEN] __tcp_ao_key_align; 26 + unsigned int tcp_sigpool_id; 27 + unsigned int digest_size; 28 + u8 prefixlen; 29 + u8 family; 30 + u8 keylen; 31 + u8 keyflags; 32 + u8 sndid; 33 + u8 rcvid; 34 + u8 maclen; 35 + struct rcu_head rcu; 36 + u8 traffic_keys[]; 37 + }; 38 + 39 + static inline u8 *rcv_other_key(struct tcp_ao_key *key) 40 + { 41 + return key->traffic_keys; 42 + } 43 + 44 + static inline u8 *snd_other_key(struct tcp_ao_key *key) 45 + { 46 + return key->traffic_keys + key->digest_size; 47 + } 48 + 49 + static inline int tcp_ao_maclen(const struct tcp_ao_key *key) 50 + { 51 + return key->maclen; 52 + } 53 + 54 + static inline int tcp_ao_len(const struct tcp_ao_key *key) 55 + { 56 + return tcp_ao_maclen(key) + sizeof(struct tcp_ao_hdr); 57 + } 58 + 59 + static inline unsigned int tcp_ao_digest_size(struct tcp_ao_key *key) 60 + { 61 + return key->digest_size; 62 + } 63 + 64 + static inline int tcp_ao_sizeof_key(const struct tcp_ao_key *key) 65 + { 66 + return sizeof(struct tcp_ao_key) + (key->digest_size << 1); 67 + } 68 + 69 + struct tcp_ao_info { 70 + /* List of tcp_ao_key's */ 71 + struct hlist_head head; 72 + /* current_key and rnext_key aren't maintained on listen sockets. 73 + * Their purpose is to cache keys on established connections, 74 + * saving needless lookups. Never dereference any of them from 75 + * listen sockets. 76 + * ::current_key may change in RX to the key that was requested by 77 + * the peer, please use READ_ONCE()/WRITE_ONCE() in order to avoid 78 + * load/store tearing. 79 + * Do the same for ::rnext_key, if you don't hold socket lock 80 + * (it's changed only by userspace request in setsockopt()). 81 + */ 82 + struct tcp_ao_key *current_key; 83 + struct tcp_ao_key *rnext_key; 84 + u32 flags; 85 + __be32 lisn; 86 + __be32 risn; 87 + struct rcu_head rcu; 88 + }; 89 + 90 + #endif /* _TCP_AO_H */
+2
include/uapi/linux/tcp.h
··· 361 361 __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; 362 362 }; 363 363 364 + #define TCP_AO_MAXKEYLEN 80 365 + 364 366 /* setsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, ...) */ 365 367 366 368 #define TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT 0x1
+13
net/ipv4/Kconfig
··· 744 744 config TCP_SIGPOOL 745 745 tristate 746 746 747 + config TCP_AO 748 + bool "TCP: Authentication Option (RFC5925)" 749 + select CRYPTO 750 + select TCP_SIGPOOL 751 + depends on 64BIT && IPV6 != m # seq-number extension needs WRITE_ONCE(u64) 752 + help 753 + TCP-AO specifies the use of stronger Message Authentication Codes (MACs), 754 + protects against replays for long-lived TCP connections, and 755 + provides more details on the association of security with TCP 756 + connections than TCP MD5 (See RFC5925) 757 + 758 + If unsure, say N. 759 + 747 760 config TCP_MD5SIG 748 761 bool "TCP: MD5 Signature Option support (RFC2385)" 749 762 select CRYPTO