[PATCH v5 17/21] net/tcp: Add option for TCP-AO to (not) hash header

From: Dmitry Safonov
Date: Mon Apr 03 2023 - 17:37:17 EST


Provide setsockopt() key flag that makes TCP-AO exclude hashing TCP
header for peers that match the key. This is needed for interraction
with middleboxes that may change TCP options, see RFC5925 (9.2).

Co-developed-by: Francesco Ruggeri <fruggeri@xxxxxxxxxx>
Signed-off-by: Francesco Ruggeri <fruggeri@xxxxxxxxxx>
Co-developed-by: Salam Noureddine <noureddine@xxxxxxxxxx>
Signed-off-by: Salam Noureddine <noureddine@xxxxxxxxxx>
Signed-off-by: Dmitry Safonov <dima@xxxxxxxxxx>
---
include/uapi/linux/tcp.h | 5 +++++
net/ipv4/tcp_ao.c | 8 +++++---
2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index ca7ed18ce67b..3275ade3293a 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -354,6 +354,11 @@ struct tcp_diag_md5sig {
#define TCP_AO_MAXKEYLEN 80

#define TCP_AO_KEYF_IFINDEX (1 << 0) /* L3 ifindex for VRF */
+#define TCP_AO_KEYF_EXCLUDE_OPT (1 << 1) /* "Indicates whether TCP
+ * options other than TCP-AO
+ * are included in the MAC
+ * calculation"
+ */

struct tcp_ao_add { /* setsockopt(TCP_AO_ADD_KEY) */
struct __kernel_sockaddr_storage addr; /* peer's address for the key */
diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
index 32c4cf2efb8f..0550bc0fe09d 100644
--- a/net/ipv4/tcp_ao.c
+++ b/net/ipv4/tcp_ao.c
@@ -566,7 +566,8 @@ int tcp_ao_hash_hdr(unsigned short int family, char *ao_hash,
WARN_ON_ONCE(1);
goto clear_hash;
}
- if (tcp_ao_hash_header(&hp, th, false,
+ if (tcp_ao_hash_header(&hp, th,
+ !!(key->keyflags & TCP_AO_KEYF_EXCLUDE_OPT),
ao_hash, hash_offset, tcp_ao_maclen(key)))
goto clear_hash;
ahash_request_set_crypt(hp.req, NULL, tmp_hash, 0);
@@ -609,7 +610,8 @@ int tcp_ao_hash_skb(unsigned short int family,
goto clear_hash;
if (tcp_ao_hash_pseudoheader(family, sk, skb, &hp, skb->len))
goto clear_hash;
- if (tcp_ao_hash_header(&hp, th, false,
+ if (tcp_ao_hash_header(&hp, th,
+ !!(key->keyflags & TCP_AO_KEYF_EXCLUDE_OPT),
ao_hash, hash_offset, tcp_ao_maclen(key)))
goto clear_hash;
if (tcp_sigpool_hash_skb_data(&hp, skb, th->doff << 2))
@@ -1345,7 +1347,7 @@ static inline int tcp_ao_verify_ipv6(struct sock *sk, struct tcp_ao_add *cmd,
}
#endif

-#define TCP_AO_KEYF_ALL (0)
+#define TCP_AO_KEYF_ALL (TCP_AO_KEYF_EXCLUDE_OPT)

static int tcp_ao_add_cmd(struct sock *sk, unsigned short int family,
sockptr_t optval, int optlen)
--
2.40.0