From: Dmitry Safonov <dima@arista.com>
To: linux-kernel@vger.kernel.org, David Ahern <dsahern@kernel.org>,
Eric Dumazet <edumazet@google.com>
Cc: Dmitry Safonov <dima@arista.com>,
Andy Lutomirski <luto@amacapital.net>,
Ard Biesheuvel <ardb@kernel.org>,
Bob Gilligan <gilligan@arista.com>,
Dan Carpenter <dan.carpenter@oracle.com>,
"David S. Miller" <davem@davemloft.net>,
Dmitry Safonov <0x7f454c46@gmail.com>,
Eric Biggers <ebiggers@kernel.org>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Francesco Ruggeri <fruggeri@arista.com>,
Herbert Xu <herbert@gondor.apana.org.au>,
Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
Ivan Delalande <colona@arista.com>,
Jakub Kicinski <kuba@kernel.org>,
Leonard Crestez <cdleonard@gmail.com>,
Paolo Abeni <pabeni@redhat.com>,
Salam Noureddine <noureddine@arista.com>,
Shuah Khan <shuah@kernel.org>,
netdev@vger.kernel.org, linux-crypto@vger.kernel.org
Subject: [PATCH v2 16/35] net/tcp: Sign SYN-ACK segments with TCP-AO
Date: Fri, 23 Sep 2022 21:13:00 +0100 [thread overview]
Message-ID: <20220923201319.493208-17-dima@arista.com> (raw)
In-Reply-To: <20220923201319.493208-1-dima@arista.com>
Similarly to RST segments, wire SYN-ACKs to TCP-AO.
tcp_rsk_used_ao() is handy here to check if the request socket used AO
and needs a signature on the outgoing segments.
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>
---
include/net/tcp.h | 4 ++++
include/net/tcp_ao.h | 6 ++++++
net/ipv4/tcp_ao.c | 14 ++++++++++++++
net/ipv4/tcp_ipv4.c | 1 +
net/ipv4/tcp_output.c | 37 +++++++++++++++++++++++++++++++------
net/ipv6/tcp_ao.c | 14 ++++++++++++++
net/ipv6/tcp_ipv6.c | 1 +
7 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index f21898bb31bd..19549be29265 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -2109,6 +2109,10 @@ struct tcp_request_sock_ops {
int sndid, int rcvid);
int (*ao_calc_key)(struct tcp_ao_key *mkt, u8 *key,
struct request_sock *sk);
+ int (*ao_synack_hash)(char *ao_hash, struct tcp_ao_key *mkt,
+ struct request_sock *req,
+ const struct sk_buff *skb,
+ int hash_offset, u32 sne);
#endif
#ifdef CONFIG_SYN_COOKIES
__u32 (*cookie_init_seq)(const struct sk_buff *skb,
diff --git a/include/net/tcp_ao.h b/include/net/tcp_ao.h
index a1d26e1a0b82..cc3f6686d5c9 100644
--- a/include/net/tcp_ao.h
+++ b/include/net/tcp_ao.h
@@ -142,6 +142,9 @@ int tcp_ao_hash_hdr(unsigned short family, char *ao_hash,
int tcp_v4_parse_ao(struct sock *sk, int optname, sockptr_t optval, int optlen);
struct tcp_ao_key *tcp_v4_ao_lookup(const struct sock *sk, struct sock *addr_sk,
int sndid, int rcvid);
+int tcp_v4_ao_synack_hash(char *ao_hash, struct tcp_ao_key *mkt,
+ struct request_sock *req, const struct sk_buff *skb,
+ int hash_offset, u32 sne);
int tcp_v4_ao_calc_key_sk(struct tcp_ao_key *mkt, u8 *key,
const struct sock *sk,
__be32 sisn, __be32 disn, bool send);
@@ -176,6 +179,9 @@ int tcp_v6_ao_hash_skb(char *ao_hash, struct tcp_ao_key *key,
const u8 *tkey, int hash_offset, u32 sne);
int tcp_v6_parse_ao(struct sock *sk, int cmd,
sockptr_t optval, int optlen);
+int tcp_v6_ao_synack_hash(char *ao_hash, struct tcp_ao_key *ao_key,
+ struct request_sock *req, const struct sk_buff *skb,
+ int hash_offset, u32 sne);
void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb);
void tcp_ao_connect_init(struct sock *sk);
diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
index a90b950781f9..6a601279852d 100644
--- a/net/ipv4/tcp_ao.c
+++ b/net/ipv4/tcp_ao.c
@@ -603,6 +603,20 @@ int tcp_v4_ao_hash_skb(char *ao_hash, struct tcp_ao_key *key,
tkey, hash_offset, sne);
}
+int tcp_v4_ao_synack_hash(char *ao_hash, struct tcp_ao_key *ao_key,
+ struct request_sock *req, const struct sk_buff *skb,
+ int hash_offset, u32 sne)
+{
+ char traffic_key[TCP_AO_MAX_HASH_SIZE] __tcp_ao_key_align;
+
+ tcp_v4_ao_calc_key_rsk(ao_key, traffic_key, req);
+
+ tcp_ao_hash_skb(AF_INET, ao_hash, ao_key, req_to_sk(req), skb,
+ traffic_key, hash_offset, sne);
+
+ return 0;
+}
+
struct tcp_ao_key *tcp_v4_ao_lookup_rsk(const struct sock *sk,
struct request_sock *req,
int sndid, int rcvid)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index cbe428957686..fedccda1dd55 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1654,6 +1654,7 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
#ifdef CONFIG_TCP_AO
.ao_lookup = tcp_v4_ao_lookup_rsk,
.ao_calc_key = tcp_v4_ao_calc_key_rsk,
+ .ao_synack_hash = tcp_v4_ao_synack_hash,
#endif
#ifdef CONFIG_SYN_COOKIES
.cookie_init_seq = cookie_v4_init_sequence,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index be92fe85e82c..c08ad98721d6 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3632,6 +3632,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
struct inet_request_sock *ireq = inet_rsk(req);
const struct tcp_sock *tp = tcp_sk(sk);
struct tcp_md5sig_key *md5 = NULL;
+ struct tcp_ao_key *ao_key = NULL;
struct tcp_out_options opts;
struct sk_buff *skb;
int tcp_header_size;
@@ -3682,16 +3683,32 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
tcp_rsk(req)->snt_synack = tcp_skb_timestamp_us(skb);
}
-#ifdef CONFIG_TCP_MD5SIG
+#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
rcu_read_lock();
- md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req));
#endif
+ if (tcp_rsk_used_ao(req)) {
+#ifdef CONFIG_TCP_AO
+ /* TODO: what should we do if the key is no longer available on
+ * the listening socket? Maybe we can try a different matching
+ * key (without sndid match). If that also fails what should
+ * we do? We currently send an unsigned synack. It's probably
+ * better to not send anything.
+ */
+ ao_key = tcp_sk(sk)->af_specific->ao_lookup(sk, req_to_sk(req),
+ tcp_rsk(req)->ao_keyid, -1);
+#endif
+ } else {
+#ifdef CONFIG_TCP_MD5SIG
+ md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk,
+ req_to_sk(req));
+#endif
+ }
skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4);
/* bpf program will be interested in the tcp_flags */
TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK;
tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5,
- NULL, foc, synack_type,
- syn_skb) + sizeof(*th);
+ ao_key, foc, synack_type, syn_skb)
+ + sizeof(*th);
skb_push(skb, tcp_header_size);
skb_reset_transport_header(skb);
@@ -3711,7 +3728,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
th->window = htons(min(req->rsk_rcv_wnd, 65535U));
- tcp_options_write(th, NULL, NULL, &opts, NULL);
+ tcp_options_write(th, NULL, tcp_rsk(req), &opts, NULL);
th->doff = (tcp_header_size >> 2);
__TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS);
@@ -3719,7 +3736,15 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
/* Okay, we have all we need - do the md5 hash if needed */
if (md5)
tcp_rsk(req)->af_specific->calc_md5_hash(opts.hash_location,
- md5, req_to_sk(req), skb);
+ md5, req_to_sk(req), skb);
+#endif
+#ifdef CONFIG_TCP_AO
+ if (ao_key)
+ tcp_rsk(req)->af_specific->ao_synack_hash(opts.hash_location,
+ ao_key, req, skb,
+ opts.hash_location - (u8 *)th, 0);
+#endif
+#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
rcu_read_unlock();
#endif
diff --git a/net/ipv6/tcp_ao.c b/net/ipv6/tcp_ao.c
index 31ae504af8e6..526bbe232a64 100644
--- a/net/ipv6/tcp_ao.c
+++ b/net/ipv6/tcp_ao.c
@@ -123,3 +123,17 @@ int tcp_v6_parse_ao(struct sock *sk, int cmd,
{
return tcp_parse_ao(sk, cmd, AF_INET6, optval, optlen);
}
+
+int tcp_v6_ao_synack_hash(char *ao_hash, struct tcp_ao_key *ao_key,
+ struct request_sock *req, const struct sk_buff *skb,
+ int hash_offset, u32 sne)
+{
+ char traffic_key[TCP_AO_MAX_HASH_SIZE] __tcp_ao_key_align;
+
+ tcp_v6_ao_calc_key_rsk(ao_key, traffic_key, req);
+
+ tcp_ao_hash_skb(AF_INET6, ao_hash, ao_key, req_to_sk(req), skb,
+ traffic_key, hash_offset, sne);
+
+ return 0;
+}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7610fdf5d519..16cea7de0851 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -838,6 +838,7 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
#ifdef CONFIG_TCP_AO
.ao_lookup = tcp_v6_ao_lookup_rsk,
.ao_calc_key = tcp_v6_ao_calc_key_rsk,
+ .ao_synack_hash = tcp_v6_ao_synack_hash,
#endif
#ifdef CONFIG_SYN_COOKIES
.cookie_init_seq = cookie_v6_init_sequence,
--
2.37.2
next prev parent reply other threads:[~2022-09-23 20:14 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-23 20:12 [PATCH v2 00/35] net/tcp: Add TCP-AO support Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 01/35] crypto: Introduce crypto_pool Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 02/35] crypto_pool: Add crypto_pool_reserve_scratch() Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 03/35] net/tcp: Separate tcp_md5sig_info allocation into tcp_md5sig_info_add() Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 04/35] net/tcp: Disable TCP-MD5 static key on tcp_md5sig_info destruction Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 05/35] net/tcp: Use crypto_pool for TCP-MD5 Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 06/35] net/ipv6: sr: Switch to using crypto_pool Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 07/35] tcp: Add TCP-AO config and structures Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 08/35] net/tcp: Introduce TCP_AO setsockopt()s Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 09/35] net/tcp: Prevent TCP-MD5 with TCP-AO being set Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 10/35] net/tcp: Calculate TCP-AO traffic keys Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 11/35] net/tcp: Add TCP-AO sign to outgoing packets Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 12/35] net/tcp: Add tcp_parse_auth_options() Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 13/35] net/tcp: Add AO sign to RST packets Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 14/35] net/tcp: Add TCP-AO sign to twsk Dmitry Safonov
2022-09-23 20:12 ` [PATCH v2 15/35] net/tcp: Wire TCP-AO to request sockets Dmitry Safonov
2022-09-24 5:23 ` kernel test robot
2022-09-23 20:13 ` Dmitry Safonov [this message]
2022-09-23 20:13 ` [PATCH v2 17/35] net/tcp: Verify inbound TCP-AO signed segments Dmitry Safonov
2022-09-24 5:43 ` kernel test robot
2022-09-23 20:13 ` [PATCH v2 18/35] net/tcp: Add TCP-AO segments counters Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 19/35] net/tcp: Add TCP-AO SNE support Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 20/35] net/tcp: Add tcp_hash_fail() ratelimited logs Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 21/35] net/tcp: Ignore specific ICMPs for TCP-AO connections Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 22/35] net/tcp: Add option for TCP-AO to (not) hash header Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 23/35] net/tcp: Add getsockopt(TCP_AO_GET) Dmitry Safonov
2022-09-24 6:44 ` kernel test robot
2022-09-23 20:13 ` [PATCH v2 24/35] net/tcp: Allow asynchronous delete for TCP-AO keys (MKTs) Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 25/35] selftests/net: Add TCP-AO library Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 26/35] selftests/net: Verify that TCP-AO complies with ignoring ICMPs Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 27/35] selftest/net: Add TCP-AO ICMPs accept test Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 28/35] selftest/tcp-ao: Add a test for MKT matching Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 29/35] selftest/tcp-ao: Add test for TCP-AO add setsockopt() command Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 30/35] selftests/tcp-ao: Add TCP-AO + TCP-MD5 + no sign listen socket tests Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 31/35] selftests/aolib: Add test/benchmark for removing MKTs Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 32/35] selftests/nettest: Remove client_pw Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 33/35] selftest/nettest: Rename md5_prefix* => auth_prefix* Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 34/35] selftests/nettest: Add TCP-AO support Dmitry Safonov
2022-09-23 20:13 ` [PATCH v2 35/35] selftests/fcnal-test.sh: Add TCP-AO tests Dmitry Safonov
2022-09-23 21:25 ` [PATCH v2 00/35] net/tcp: Add TCP-AO support Dmitry Safonov
2022-09-27 1:57 ` David Ahern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220923201319.493208-17-dima@arista.com \
--to=dima@arista.com \
--cc=0x7f454c46@gmail.com \
--cc=ardb@kernel.org \
--cc=cdleonard@gmail.com \
--cc=colona@arista.com \
--cc=dan.carpenter@oracle.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=ebiederm@xmission.com \
--cc=ebiggers@kernel.org \
--cc=edumazet@google.com \
--cc=fruggeri@arista.com \
--cc=gilligan@arista.com \
--cc=herbert@gondor.apana.org.au \
--cc=kuba@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=netdev@vger.kernel.org \
--cc=noureddine@arista.com \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.